Changed everything to not use Data.Internals anymore

This commit is contained in:
Elytherion
2019-07-02 19:17:53 +02:00
parent f5122b777c
commit b0dec717e1
97 changed files with 1598 additions and 807 deletions
+1
View File
@@ -7,6 +7,7 @@ npm-debug.log*
.rpt2_cache
.esm-cache
app/**/*.js
app/**/*.js.map
!app/index.js
/installer/
electron-builder.env
-1
View File
@@ -17,6 +17,5 @@
require = require('esm')(module)
require('./entry.js')
</script>
<!-- <script src="./testmodule.js" type="module"></script> -->
</body>
</html>
+3 -2
View File
@@ -7,15 +7,16 @@ import * as fs from "fs";
import { extname, join } from "path";
import { tryIO } from "../../Control/Exception";
import { and } from "../../Data/Bool";
import { Either, eitherToMaybe, fromLeft, fromLeft_, fromRight_, isLeft, isRight, second } from "../../Data/Either";
import { Either, fromLeft, isLeft, isRight, second } from "../../Data/Either";
import { eitherToMaybe, fromLeft_, fromRight_ } from "../../Data/Either/Extra";
import { cnst, flip } from "../../Data/Function";
import { fmap, fmapF } from "../../Data/Functor";
import { List, notNull } from "../../Data/List";
import { altF_, bind, bindF, ensure, fromJust, fromMaybe, isJust, Just, listToMaybe, Maybe, maybe, maybeToUndefined, Nothing } from "../../Data/Maybe";
import { any, keysSet, lookup, lookupF, mapMaybe, OrderedMap } from "../../Data/OrderedMap";
import { differenceF, map } from "../../Data/OrderedSet";
import { fst, Pair } from "../../Data/Pair";
import { Record, StringKeyObject, toObject } from "../../Data/Record";
import { fst, Pair } from "../../Data/Tuple";
import { IO, readFile, runIO, writeFile } from "../../System/IO";
import { ActionTypes } from "../Constants/ActionTypes";
import { IdPrefixes } from "../Constants/IdPrefixes";
+1 -1
View File
@@ -3,8 +3,8 @@ import { set } from "../../Data/Lens";
import { List, subscriptF } from "../../Data/List";
import { bind, bindF, ensure, fromJust, isJust, isNothing, join, Just, liftM2, Maybe } from "../../Data/Maybe";
import { lookup } from "../../Data/OrderedMap";
import { Pair } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { Pair } from "../../Data/Tuple";
import { ActionTypes } from "../Constants/ActionTypes";
import { ActivatableActivationOptions } from "../Models/Actions/ActivatableActivationOptions";
import { ActivatableDeactivationOptions } from "../Models/Actions/ActivatableDeactivationOptions";
+1 -1
View File
@@ -2,8 +2,8 @@ import { List } from "../../../Data/List";
import { Maybe } from "../../../Data/Maybe";
import { OrderedMap } from "../../../Data/OrderedMap";
import { OrderedSet } from "../../../Data/OrderedSet";
import { Pair } from "../../../Data/Pair";
import { Record, RecordI } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { ReduxActions } from "../../Actions/Actions";
import { TabId } from "../../Utilities/LocationUtils";
import { ActivatableDependent } from "../ActiveEntries/ActivatableDependent";
+1 -1
View File
@@ -1,7 +1,7 @@
import { List } from "../../../Data/List";
import { Maybe, Nothing } from "../../../Data/Maybe";
import { Pair } from "../../../Data/Pair";
import { fromDefault, makeLenses, Record } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { Categories } from "../../Constants/Categories";
import { Die } from "./sub/Die";
import { SourceLink } from "./sub/SourceLink";
+1 -1
View File
@@ -1,5 +1,5 @@
import { fst, Pair, snd } from "../../../../Data/Pair";
import { fromDefault } from "../../../../Data/Record";
import { fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { prefixId } from "../../../Utilities/IDUtils";
+1 -1
View File
@@ -1,6 +1,6 @@
import { isList, List, map } from "../../../../Data/List";
import { fst, Pair, snd } from "../../../../Data/Pair";
import { fromDefault } from "../../../../Data/Record";
import { fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { prefixId } from "../../../Utilities/IDUtils";
import { pairToIncreaseSkill } from "./IncreaseSkill";
+1 -1
View File
@@ -1,5 +1,5 @@
import { Pair } from "../../../../Data/Pair";
import { fromDefault } from "../../../../Data/Record";
import { Pair } from "../../../../Data/Tuple";
export interface SourceLink {
id: string
+1 -1
View File
@@ -3,7 +3,7 @@ import { over, set } from "../../Data/Lens";
import { modifyAt } from "../../Data/List";
import { Just } from "../../Data/Maybe";
import { adjust } from "../../Data/OrderedMap";
import { fst, snd } from "../../Data/Pair";
import { fst, snd } from "../../Data/Tuple";
import * as DisAdvActions from "../Actions/DisAdvActions";
import * as SpecialAbilitiesActions from "../Actions/SpecialAbilitiesActions";
import { ActionTypes } from "../Constants/ActionTypes";
+1 -2
View File
@@ -5,9 +5,8 @@ import { over, set } from "../../Data/Lens";
import { consF, List } from "../../Data/List";
import { and, elem, fromJust, isJust, isNothing, Just, or } from "../../Data/Maybe";
import { insert, OrderedMap } from "../../Data/OrderedMap";
import { snd } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { fst } from "../../Data/Tuple";
import { fst, snd } from "../../Data/Tuple";
import { RedoAction, UndoAction } from "../Actions/HistoryActions";
import { ReceiveImportedHeroAction, ReceiveInitialDataAction } from "../Actions/IOActions";
import { ActionTypes } from "../Constants/ActionTypes";
+1 -1
View File
@@ -3,8 +3,8 @@ import { ident } from "../../Data/Function";
import { over, set } from "../../Data/Lens";
import { bind, fromJust, isJust, Just, Maybe, maybe, Nothing } from "../../Data/Maybe";
import { adjust, any, deleteLookupWithKey, insert, lookup, OrderedMap, sdelete } from "../../Data/OrderedMap";
import { fst, snd } from "../../Data/Pair";
import { fromDefault, makeLenses, Record } from "../../Data/Record";
import { fst, snd } from "../../Data/Tuple";
import * as HerolistActions from "../Actions/HerolistActions";
import * as IOActions from "../Actions/IOActions";
import { ActionTypes } from "../Constants/ActionTypes";
+1 -1
View File
@@ -1,8 +1,8 @@
import { cnst, ident } from "../../Data/Function";
import { set } from "../../Data/Lens";
import { bind, fromMaybe, isJust, Just, Maybe, Nothing } from "../../Data/Maybe";
import { fst } from "../../Data/Pair";
import { fromDefault, makeLenses, Record } from "../../Data/Record";
import { fst } from "../../Data/Tuple";
import { ReceiveInitialDataAction } from "../Actions/IOActions";
import { SetLocaleAction } from "../Actions/LocaleActions";
import { ActionTypes } from "../Constants/ActionTypes";
+1 -1
View File
@@ -1,8 +1,8 @@
import { ident } from "../../Data/Function";
import { over, set } from "../../Data/Lens";
import { isJust, Just, Nothing } from "../../Data/Maybe";
import { snd } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { snd } from "../../Data/Tuple";
import * as DisAdvActions from "../Actions/DisAdvActions";
import * as ProfileActions from "../Actions/ProfileActions";
import { ActionTypes } from "../Constants/ActionTypes";
+1 -1
View File
@@ -1,5 +1,5 @@
import { cnst, ident } from "../../Data/Function";
import { snd } from "../../Data/Pair";
import { snd } from "../../Data/Tuple";
import { ReceiveInitialDataAction } from "../Actions/IOActions";
import { ActionTypes } from "../Constants/ActionTypes";
import { WikiModelRecord } from "../Models/Wiki/WikiModel";
+1 -2
View File
@@ -4,9 +4,8 @@ import { consF, elem, filter, filterMulti, foldr, intercalate, List, map, notEle
import { bindF, fromMaybe, Just, liftM2, liftM3, listToMaybe, mapMaybe, Maybe, Nothing } from "../../Data/Maybe";
import { insert, lookup, OrderedMap } from "../../Data/OrderedMap";
import { member, OrderedSet } from "../../Data/OrderedSet";
import { uncurryN } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { uncurryN3 } from "../../Data/Tuple/Curry";
import { uncurryN, uncurryN3 } from "../../Data/Tuple/Curry";
import { ActivatableCategory, Categories } from "../Constants/Categories";
import { IdPrefixes } from "../Constants/IdPrefixes";
import { ActivatableDependent } from "../Models/ActiveEntries/ActivatableDependent";
@@ -2,8 +2,8 @@ import { cnst } from "../../Data/Function";
import { fmap } from "../../Data/Functor";
import { foldr, fromArray } from "../../Data/List";
import { any, elem, fromJust, isJust, isMaybe, join, Just, liftM2, Maybe, Nothing } from "../../Data/Maybe";
import { uncurryN3 } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { uncurryN3 } from "../../Data/Tuple/Curry";
import { HeroModel } from "../Models/Hero/HeroModel";
import { AdventurePointsCategories } from "../Models/View/AdventurePointsCategories";
import { ExperienceLevel } from "../Models/Wiki/ExperienceLevel";
+1 -1
View File
@@ -1,7 +1,7 @@
import { append, partition } from "../../Data/List";
import { elems } from "../../Data/OrderedMap";
import { uncurryN } from "../../Data/Pair";
import { bimap, fst, snd } from "../../Data/Tuple";
import { uncurryN } from "../../Data/Tuple/Curry";
import { Book } from "../Models/Wiki/Book";
import { createMaybeSelector } from "../Utilities/createMaybeSelector";
import { compareLocale } from "../Utilities/I18n";
@@ -3,9 +3,8 @@ import { fmap, fmapF } from "../../Data/Functor";
import { cons, consF, elem, List, map, maximum } from "../../Data/List";
import { fromJust, isJust, Just, liftM2, Maybe, Nothing, or } from "../../Data/Maybe";
import { findWithDefault, foldrWithKey, lookup } from "../../Data/OrderedMap";
import { uncurryN } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { uncurryN4 } from "../../Data/Tuple/Curry";
import { uncurryN, uncurryN4 } from "../../Data/Tuple/Curry";
import { IdPrefixes } from "../Constants/IdPrefixes";
import { ActivatableDependent } from "../Models/ActiveEntries/ActivatableDependent";
import { createSkillDependentWithValue6, SkillDependent } from "../Models/ActiveEntries/SkillDependent";
@@ -2,8 +2,8 @@ import { fmap, fmapF } from "../../Data/Functor";
import { elem, foldr, List, snoc } from "../../Data/List";
import { bindF, fromMaybe, Just, liftM2, listToMaybe, maybe, Maybe, Nothing, or } from "../../Data/Maybe";
import { elems, fromList } from "../../Data/OrderedMap";
import { fst, Pair, snd } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { fst, Pair, snd } from "../../Data/Tuple";
import { ActivatableDependent } from "../Models/ActiveEntries/ActivatableDependent";
import { ActiveObject } from "../Models/ActiveEntries/ActiveObject";
import { AttributeDependent } from "../Models/ActiveEntries/AttributeDependent";
+1 -1
View File
@@ -2,7 +2,7 @@ import { ident } from "../../Data/Function";
import { map, notNull } from "../../Data/List";
import { elems, foldr } from "../../Data/OrderedMap";
import { insert, OrderedSet } from "../../Data/OrderedSet";
import { uncurryN3 } from "../../Data/Pair";
import { uncurryN3 } from "../../Data/Tuple/Curry";
import { HeroModel } from "../Models/Hero/HeroModel";
import { heroReducer } from "../Reducers/heroReducer";
import { createMaybeSelector } from "../Utilities/createMaybeSelector";
+1 -1
View File
@@ -3,8 +3,8 @@ import { cnst } from "../../Data/Function";
import { any, fnull, isList } from "../../Data/List";
import { bindF, ensure, fromJust, isJust, maybe } from "../../Data/Maybe";
import { elems, lookup } from "../../Data/OrderedMap";
import { uncurryN } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { uncurryN } from "../../Data/Tuple/Curry";
import { ActivatableDependent } from "../Models/ActiveEntries/ActivatableDependent";
import { Pact } from "../Models/Hero/Pact";
import { isPactRequirement } from "../Models/Wiki/prerequisites/PactRequirement";
+1 -1
View File
@@ -5,8 +5,8 @@ import { over } from "../../Data/Lens";
import { all, cons, Cons, consF, elem, elemF, filter, find, foldr, intercalate, List, ListI, map, subscriptF } from "../../Data/List";
import { alt, bind, bindF, ensure, fromMaybe, fromMaybe_, imapMaybe, Just, liftM2, liftM4, mapM, mapMaybe, maybe, Maybe } from "../../Data/Maybe";
import { elems, lookup, lookupF, OrderedMap } from "../../Data/OrderedMap";
import { uncurryN, uncurryN3, uncurryN4, uncurryN8 } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { uncurryN, uncurryN3, uncurryN4, uncurryN8 } from "../../Data/Tuple/Curry";
import { Categories } from "../Constants/Categories";
import { ActiveObjectWithId } from "../Models/ActiveEntries/ActiveObjectWithId";
import { Sex } from "../Models/Hero/heroTypeHelpers";
+2 -1
View File
@@ -1,7 +1,8 @@
import { fmap } from "../../Data/Functor";
import { OrderedMap } from "../../Data/OrderedMap";
import { Pair, uncurryN } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { Pair } from "../../Data/Tuple";
import { uncurryN } from "../../Data/Tuple/Curry";
import { Rules } from "../Models/Hero/Rules";
import { Book } from "../Models/Wiki/Book";
import { isMaybeActive } from "../Utilities/Activatable/isActive";
+1 -1
View File
@@ -3,7 +3,7 @@ import { fmap } from "../../Data/Functor";
import { foldr, map } from "../../Data/List";
import { fromMaybe, liftM3, maybe } from "../../Data/Maybe";
import { elems, insertF, lookup, OrderedMap } from "../../Data/OrderedMap";
import { uncurryN, uncurryN3, uncurryN4 } from "../../Data/Pair";
import { uncurryN, uncurryN3, uncurryN4 } from "../../Data/Tuple/Curry";
import { createPlainSkillDependent } from "../Models/ActiveEntries/SkillDependent";
import { HeroModel } from "../Models/Hero/HeroModel";
import { EntryRating } from "../Models/Hero/heroTypeHelpers";
+2 -1
View File
@@ -6,8 +6,9 @@ import { append, consF, countWith, elemF, List, map, notNull, partition } from "
import { all, any, bindF, ensure, fromMaybe_, Just, liftM2, listToMaybe, mapMaybe, Maybe, maybe, Nothing } from "../../Data/Maybe";
import { elems, lookup, lookupF, OrderedMap } from "../../Data/OrderedMap";
import { member } from "../../Data/OrderedSet";
import { fst, snd, uncurryN, uncurryN3, uncurryN5, uncurryN6, uncurryN8 } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { fst, snd } from "../../Data/Tuple";
import { uncurryN, uncurryN3, uncurryN5, uncurryN6, uncurryN8 } from "../../Data/Tuple/Curry";
import { ActivatableDependent } from "../Models/ActiveEntries/ActivatableDependent";
import { ActivatableSkillDependent, createInactiveActivatableSkillDependent } from "../Models/ActiveEntries/ActivatableSkillDependent";
import { ActiveObject } from "../Models/ActiveEntries/ActiveObject";
@@ -4,8 +4,8 @@ import { fmap } from "../../../Data/Functor";
import { Lens_, over, set, view } from "../../../Data/Lens";
import { all, append, concatMap, elem, empty, filter, findIndex, flength, foldr, isList, List, ListI, map, modifyAt, partition, pure } from "../../../Data/List";
import { alt, and, fromJust, fromMaybe, isJust, isNothing, Just, liftM2, Maybe, Nothing, or } from "../../../Data/Maybe";
import { fst, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { fst, snd } from "../../../Data/Tuple";
import { HeroModelL, HeroModelRecord } from "../../Models/Hero/HeroModel";
import { StyleDependency, StyleDependencyL } from "../../Models/Hero/StyleDependency";
import { SpecialAbility } from "../../Models/Wiki/SpecialAbility";
@@ -14,9 +14,9 @@ import { over, set } from "../../../Data/Lens";
import { consF, countWith, elem, elemF, filter, find, flength, fnull, foldr, isList, List, map, mapByIdKeyMap, maximum, notElem, notElemF, notNull, subscript } from "../../../Data/List";
import { all, bind, bindF, ensure, fromJust, fromMaybe, guard, guard_, isJust, join, Just, liftM2, listToMaybe, mapMaybe, Maybe, maybe, Nothing, or } from "../../../Data/Maybe";
import { alter, elems, foldrWithKey, isOrderedMap, lookup, lookupF, member, OrderedMap } from "../../../Data/OrderedMap";
import { fst, Pair, snd } from "../../../Data/Pair";
import { Record, RecordI } from "../../../Data/Record";
import { showP } from "../../../Data/Show";
import { fst, Pair, snd } from "../../../Data/Tuple";
import { ActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { ActivatableSkillDependent } from "../../Models/ActiveEntries/ActivatableSkillDependent";
import { ActiveObject } from "../../Models/ActiveEntries/ActiveObject";
@@ -5,9 +5,9 @@ import { fmap, fmapF } from "../../../Data/Functor";
import { over, set } from "../../../Data/Lens";
import { countWith, elemF, filter, find, flength, foldr, imap, isList, List, map, notElem, notElemF, subscript, subscriptF, sum, take } from "../../../Data/List";
import { alt, altF, altF_, any, bind, bindF, ensure, fromJust, fromMaybe, guard, isJust, isNothing, join, joinMaybeList, Just, liftM2, mapMaybe, Maybe, maybe, maybe_, Nothing, or, then, thenF } from "../../../Data/Maybe";
import { bimap, first, Pair, second, snd } from "../../../Data/Pair";
import { fromDefault, makeLenses, Omit, Record } from "../../../Data/Record";
import { showP } from "../../../Data/Show";
import { bimap, first, Pair, second, snd } from "../../../Data/Tuple";
import { ActivatableActivationOptions, ActivatableActivationOptionsL } from "../../Models/Actions/ActivatableActivationOptions";
import { ActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { ActiveObject } from "../../Models/ActiveEntries/ActiveObject";
@@ -1,6 +1,6 @@
import { any } from "../../../Data/List";
import { Pair } from "../../../Data/Pair";
import { member, Record } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { ActiveActivatable } from "../../Models/View/ActiveActivatable";
import { InactiveActivatable } from "../../Models/View/InactiveActivatable";
import { Advantage } from "../../Models/Wiki/Advantage";
@@ -4,8 +4,8 @@ import { fmap, fmapF } from "../../../Data/Functor";
import { any, countWith, countWithByKeyMaybe, elemF, find, flength, foldl, foldr, isList, lastS, List, take } from "../../../Data/List";
import { all, altF, bind, bindF, elem, ensure, fromJust, fromMaybe, isJust, isNothing, Just, liftM2, listToMaybe, Maybe, Nothing, or, sum } from "../../../Data/Maybe";
import { alter, empty, findWithDefault, lookup, OrderedMap } from "../../../Data/OrderedMap";
import { fst, Pair, snd } from "../../../Data/Pair";
import { fromDefault, Record } from "../../../Data/Record";
import { fst, Pair, snd } from "../../../Data/Tuple";
import { ActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { ActiveObject } from "../../Models/ActiveEntries/ActiveObject";
import { HeroModel, HeroModelRecord } from "../../Models/Hero/HeroModel";
@@ -1,4 +1,4 @@
import { bimap, fst, Pair, snd } from "../../../Data/Pair";
import { bimap, fst, Pair, snd } from "../../../Data/Tuple";
import { add, inc, max, multiply, negate, subtractBy } from "../mathUtils";
import { pipe } from "../pipe";
+1 -1
View File
@@ -1,6 +1,6 @@
import { join } from "path";
import { tryIO } from "../../Control/Exception";
import { eitherToMaybe } from "../../Data/Either";
import { eitherToMaybe } from "../../Data/Either/Extra";
import { ident } from "../../Data/Function";
import { fmap } from "../../Data/Functor";
import { all, fromArray, List } from "../../Data/List";
+1 -1
View File
@@ -3,7 +3,7 @@ import { fmap } from "../../Data/Functor";
import { fnull, intercalate, List, subscript, unsnoc } from "../../Data/List";
import { maybe, Maybe, normalize, sum } from "../../Data/Maybe";
import { toOrdering } from "../../Data/Ord";
import { fst, snd } from "../../Data/Pair";
import { fst, snd } from "../../Data/Tuple";
import { L10n, L10nRecord } from "../Models/Wiki/L10n";
import { pipe } from "./pipe";
import { isString } from "./typeCheckUtils";
+4 -6
View File
@@ -1,19 +1,17 @@
import { remote } from "electron";
import { tryIO } from "../../Control/Exception";
import { Either, fromLeft_, fromRight_, isLeft, Left, Right } from "../../Data/Either";
import { Either, isLeft, Left, Right } from "../../Data/Either";
import { fromLeft_, fromRight_ } from "../../Data/Either/Extra";
import { cnst } from "../../Data/Function";
import { fmap, fmapF } from "../../Data/Functor";
import { Internals } from "../../Data/Internals";
import { flength, fromArray, List, subscript } from "../../Data/List";
import { fromMaybe, normalize, Nothing } from "../../Data/Maybe";
import { bimap, fst, Pair, snd } from "../../Data/Pair";
import { bimap, fst, Pair, snd } from "../../Data/Tuple";
import { Unit } from "../../Data/Unit";
import { bind, pure } from "../../System/IO";
import { bind, IO, pure } from "../../System/IO";
import { divideBy, inc } from "./mathUtils";
import { pipe } from "./pipe";
import IO = Internals.IO
/**
* Prints windows' web page as PDF with Chromium's preview printing custom settings.
*/
+1 -1
View File
@@ -4,8 +4,8 @@ import { consF, countWith, foldr, List, maximum, maximumNonNegative, minimum } f
import { elem, Just, maybe, Maybe, Nothing, sum } from "../../../Data/Maybe";
import { lookupF, OrderedMap } from "../../../Data/OrderedMap";
import { } from "../../../Data/OrderedSet";
import { Pair } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { ActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { ActiveObject } from "../../Models/ActiveEntries/ActiveObject";
import { AttributeDependent } from "../../Models/ActiveEntries/AttributeDependent";
@@ -7,8 +7,8 @@ import { set } from "../../../Data/Lens";
import { all, any, concat, elem, elemF, foldl, isList, List, map, sortBy } from "../../../Data/List";
import { and, bind, bindF, catMaybes, ensure, fromJust, fromMaybe, isJust, isNothing, Just, Maybe, maybe, maybeToList, Nothing, or } from "../../../Data/Maybe";
import { lookupF, OrderedMap, toList } from "../../../Data/OrderedMap";
import { fst, Pair, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { fst, Pair, snd } from "../../../Data/Tuple";
import { IdPrefixes } from "../../Constants/IdPrefixes";
import { ActivatableDependent, isActivatableDependent, isExtendedActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { ActivatableSkillDependent } from "../../Models/ActiveEntries/ActivatableSkillDependent";
@@ -1,12 +1,13 @@
import { Either, Left, mapM, maybeToEither, Right, second } from "../../../../../Data/Either";
import { Either, Left, mapM, Right, second } from "../../../../../Data/Either";
import { maybeToEither } from "../../../../../Data/Either/Extra";
import { flip } from "../../../../../Data/Function";
import { fmap } from "../../../../../Data/Functor";
import { fromArray, isInfixOf, List, NonEmptyList, splitOn, uncons } from "../../../../../Data/List";
import { bindF, ensure, fromJust, fromMaybe, isNothing, Just, Maybe, Nothing } from "../../../../../Data/Maybe";
import { fromList } from "../../../../../Data/OrderedMap";
import { fst, Pair, snd } from "../../../../../Data/Pair";
import { show } from "../../../../../Data/Show";
import { parseJSON } from "../../../../../Data/String/JSON";
import { fst, Pair, snd } from "../../../../../Data/Tuple";
import { traceShow } from "../../../../../Debug/Trace";
import { RequireActivatable } from "../../../../Models/Wiki/prerequisites/ActivatableRequirement";
import { CultureRequirement } from "../../../../Models/Wiki/prerequisites/CultureRequirement";
@@ -2,7 +2,7 @@ import { Either } from "../../../../../Data/Either";
import { append, empty, List, map, notNullStr } from "../../../../../Data/List";
import { ensure, fromMaybe, Maybe } from "../../../../../Data/Maybe";
import { fromList } from "../../../../../Data/OrderedMap";
import { Pair } from "../../../../../Data/Pair";
import { Pair } from "../../../../../Data/Tuple";
import { Advantage } from "../../../../Models/Wiki/Advantage";
import { toNatural } from "../../../NumberUtils";
import { Expect } from "../../showExpected";
@@ -2,8 +2,8 @@ import { Either } from "../../../../../Data/Either";
import { flip } from "../../../../../Data/Function";
import { Cons, flength, List, splitOn } from "../../../../../Data/List";
import { bindF, ensure, liftM2, listToMaybe, Maybe, maybe, Nothing } from "../../../../../Data/Maybe";
import { Pair } from "../../../../../Data/Pair";
import { Record } from "../../../../../Data/Record";
import { Pair } from "../../../../../Data/Tuple";
import { SourceLink } from "../../../../Models/Wiki/sub/SourceLink";
import { toNatural } from "../../../NumberUtils";
import { Expect } from "../../showExpected";
@@ -1,6 +1,6 @@
import { notNull, notNullStr } from "../../../../Data/List";
import { Just, Nothing } from "../../../../Data/Maybe";
import { Pair } from "../../../../Data/Pair";
import { Pair } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { SelectOption } from "../../../Models/Wiki/sub/SelectOption";
import { prefixId } from "../../IDUtils";
+1 -1
View File
@@ -1,7 +1,7 @@
import { empty, List, map, notNull } from "../../../../Data/List";
import { fromMaybe, maybe, Nothing } from "../../../../Data/Maybe";
import { fst, Pair, snd } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { Culture } from "../../../Models/Wiki/Culture";
import { CommonProfession } from "../../../Models/Wiki/sub/CommonProfession";
+3 -2
View File
@@ -1,9 +1,10 @@
import { Either, fromRight_, isLeft, mapM, maybeToEither, maybeToEither_ } from "../../../../Data/Either";
import { Either, isLeft, mapM } from "../../../../Data/Either";
import { fromRight_, maybeToEither, maybeToEither_ } from "../../../../Data/Either/Extra";
import { List } from "../../../../Data/List";
import { ensure, liftM2 } from "../../../../Data/Maybe";
import { fromList, lookupF, OrderedMap } from "../../../../Data/OrderedMap";
import { Pair } from "../../../../Data/Pair";
import { show } from "../../../../Data/Show";
import { Pair } from "../../../../Data/Tuple";
import { L10n, L10nRecord } from "../../../Models/Wiki/L10n";
import { mensureMapNonEmptyString, mensureMapNonEmptyStringList } from "../validateMapValueUtils";
import { lookupKeyValid, mapMNamed, TableType } from "../validateValueUtils";
+1 -1
View File
@@ -1,7 +1,7 @@
import { fmap } from "../../../../Data/Functor";
import { empty, List, map } from "../../../../Data/List";
import { fromMaybe, Nothing } from "../../../../Data/Maybe";
import { first, fst, Pair, snd } from "../../../../Data/Pair";
import { first, fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { Race } from "../../../Models/Wiki/Race";
import { Die } from "../../../Models/Wiki/sub/Die";
@@ -1,7 +1,7 @@
import { fmap } from "../../../../Data/Functor";
import { map } from "../../../../Data/List";
import { Nothing } from "../../../../Data/Maybe";
import { fst, Pair, snd } from "../../../../Data/Pair";
import { fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { RaceVariant } from "../../../Models/Wiki/RaceVariant";
import { Die } from "../../../Models/Wiki/sub/Die";
+1 -1
View File
@@ -2,9 +2,9 @@ import { liftM2 } from "../../../../Data/Either";
import { fmap } from "../../../../Data/Functor";
import { fromArray, List, lookup, map, NonEmptyList, notNullStr } from "../../../../Data/List";
import { any, ensure, fromJust, Just, Maybe, maybe_, Nothing, Some } from "../../../../Data/Maybe";
import { fst, Pair, snd } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { parseJSON } from "../../../../Data/String/JSON";
import { fst, Pair, snd } from "../../../../Data/Tuple";
import { IdPrefixes } from "../../../Constants/IdPrefixes";
import { RequireActivatable } from "../../../Models/Wiki/prerequisites/ActivatableRequirement";
import { Skill } from "../../../Models/Wiki/Skill";
+2 -1
View File
@@ -1,4 +1,5 @@
import { bindF, Either, Left, maybeToEither, Right } from "../../../Data/Either";
import { bindF, Either, Left, Right } from "../../../Data/Either";
import { maybeToEither } from "../../../Data/Either/Extra";
import { fmap } from "../../../Data/Functor";
import { cons, empty, filter, find, flength, head, ifoldr, lines, List, map, notNull, notNullStr, replaceStr, splitOn, uncons, zip } from "../../../Data/List";
import { ensure, fromJust, isJust, mapMaybe } from "../../../Data/Maybe";
+2 -1
View File
@@ -1,4 +1,5 @@
import { bimap, Either, first, fromRight_, isLeft, maybeToEither, Right } from "../../../Data/Either";
import { bimap, Either, first, isLeft, Right } from "../../../Data/Either";
import { fromRight_, maybeToEither } from "../../../Data/Either/Extra";
import { appendStr, find, List, notNullStr } from "../../../Data/List";
import { bind, bindF, elem, ensure, fromJust, isJust, Just, Maybe, Nothing } from "../../../Data/Maybe";
import { lookup, lookupF, OrderedMap } from "../../../Data/OrderedMap";
+3 -2
View File
@@ -1,6 +1,7 @@
import * as path from "path";
import * as xlsx from "xlsx";
import { bind, bindF, Either, first, fromRight_, isLeft, Left, mapM, maybeToEither } from "../../../Data/Either";
import { bind, bindF, Either, first, isLeft, Left, mapM } from "../../../Data/Either";
import { fromRight_, maybeToEither } from "../../../Data/Either/Extra";
import { equals } from "../../../Data/Eq";
import { flip, thrush } from "../../../Data/Function";
import { fmap } from "../../../Data/Functor";
@@ -9,8 +10,8 @@ import { all, append, consF, empty, foldr, List, map, notElemF } from "../../../
import { catMaybes, ensure, fromMaybe, Just, mapMaybe, Maybe, Nothing } from "../../../Data/Maybe";
import { adjust, elems, fromList, insert, lookupF, mapMEitherWithKey, OrderedMap } from "../../../Data/OrderedMap";
import { OrderedSet } from "../../../Data/OrderedSet";
import { fst, Pair, snd } from "../../../Data/Pair";
import { makeLenses, member, Record } from "../../../Data/Record";
import { fst, Pair, snd } from "../../../Data/Tuple";
import { Categories } from "../../Constants/Categories";
import { AdvantageL } from "../../Models/Wiki/Advantage";
import { Book } from "../../Models/Wiki/Book";
@@ -1,12 +1,13 @@
import { Either, maybeToEither_ } from "../../../Data/Either";
import { Either } from "../../../Data/Either";
import { maybeToEither_ } from "../../../Data/Either/Extra";
import { equals } from "../../../Data/Eq";
import { fmap } from "../../../Data/Functor";
import { inRange } from "../../../Data/Ix";
import { Cons, flength, List, notNullStr, splitOn } from "../../../Data/List";
import { bindF, ensure, fromMaybe, Just, liftM2, mapM, Maybe, maybe, Nothing } from "../../../Data/Maybe";
import { fromList, OrderedSet } from "../../../Data/OrderedSet";
import { Pair } from "../../../Data/Pair";
import { show } from "../../../Data/Show";
import { Pair } from "../../../Data/Tuple";
import { toFloat, toInt, toNatural } from "../NumberUtils";
import { pipe } from "../pipe";
import { Expect } from "./showExpected";
+2 -1
View File
@@ -1,4 +1,5 @@
import { Either, first, fromRight_, isEither, isLeft, isRight, Left, Right, RightI } from "../../../Data/Either";
import { Either, first, isEither, isLeft, isRight, Left, Right, RightI } from "../../../Data/Either";
import { fromRight_ } from "../../../Data/Either/Extra";
import { appendStr, List, notNullStr } from "../../../Data/List";
import { bindF, ensure, Maybe } from "../../../Data/Maybe";
import { showP } from "../../../Data/Show";
+1 -1
View File
@@ -2,8 +2,8 @@ import { any, filter, fnull, List } from "../../Data/List";
import { fromJust, isJust, Maybe } from "../../Data/Maybe";
import { lookup, lookupF } from "../../Data/OrderedMap";
import { member } from "../../Data/OrderedSet";
import { fst, snd } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { fst, snd } from "../../Data/Tuple";
import { Rules } from "../Models/Hero/Rules";
import { Book } from "../Models/Wiki/Book";
import { SourceLink } from "../Models/Wiki/sub/SourceLink";
+1 -1
View File
@@ -1,6 +1,6 @@
import { join } from "path";
import { tryIO } from "../../Control/Exception";
import { eitherToMaybe } from "../../Data/Either";
import { eitherToMaybe } from "../../Data/Either/Extra";
import { fmap } from "../../Data/Functor";
import { and, bindF } from "../../Data/Maybe";
import { parseJSON } from "../../Data/String/JSON";
+1 -1
View File
@@ -1,7 +1,7 @@
import { unfoldr } from "../../Data/List";
import { Just, Nothing } from "../../Data/Maybe";
import { Pair } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { Pair } from "../../Data/Tuple";
import { DropdownOption } from "../Views/Universal/Dropdown";
import { toRoman } from "./NumberUtils";
@@ -6,8 +6,8 @@ import { any, elemF, filter, List, pure } from "../../Data/List";
import { bindF, elem, ensure, fromJust, fromMaybe, guard, isJust, join, Just, liftM2, liftM3, listToMaybe, mapMaybe, Maybe, maybe, maybeToNullable, Nothing } from "../../Data/Maybe";
import { elems, lookup, lookupF, OrderedMap, size, sum } from "../../Data/OrderedMap";
import { OrderedSet } from "../../Data/OrderedSet";
import { fst, Pair, snd } from "../../Data/Pair";
import { Record } from "../../Data/Record";
import { fst, Pair, snd } from "../../Data/Tuple";
import { LanguagesSelectionListItem } from "../Models/Hero/LanguagesSelectionListItem";
import { ScriptsSelectionListItem } from "../Models/Hero/ScriptsSelectionListItem";
import { Cantrip } from "../Models/Wiki/Cantrip";
+1 -1
View File
@@ -3,8 +3,8 @@ import { flip, ident } from "../../Data/Function";
import { set } from "../../Data/Lens";
import { cons, elem, empty, List, uncons } from "../../Data/List";
import { maybe } from "../../Data/Maybe";
import { fst, Pair, snd } from "../../Data/Pair";
import { fromDefault, makeLenses, Record } from "../../Data/Record";
import { fst, Pair, snd } from "../../Data/Tuple";
import { ActionTypes } from "../Constants/ActionTypes";
export interface UndoState<S> {
@@ -2,8 +2,8 @@ import classNames from "classnames";
import * as React from "react";
import { notNullStrUndef } from "../../../Data/List";
import { fromJust, fromMaybeR, isJust, Maybe, maybeToUndefined } from "../../../Data/Maybe";
import { fst, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { fst, snd } from "../../../Data/Tuple";
import { ActivatableActivationOptions } from "../../Models/Actions/ActivatableActivationOptions";
import { HeroModel } from "../../Models/Hero/HeroModel";
import { InputTextEvent } from "../../Models/Hero/heroTypeHelpers";
@@ -3,8 +3,8 @@ import { fmap } from "../../../../Data/Functor";
import { filter, intercalate, List } from "../../../../Data/List";
import { mapMaybe } from "../../../../Data/Maybe";
import { lookupF, memberF, OrderedMap } from "../../../../Data/OrderedMap";
import { fst, isPair, snd } from "../../../../Data/Pair";
import { Record, RecordBase } from "../../../../Data/Record";
import { fst, isTuple, snd } from "../../../../Data/Tuple";
import { Book } from "../../../Models/Wiki/Book";
import { L10n, L10nRecord } from "../../../Models/Wiki/L10n";
import { SourceLink } from "../../../Models/Wiki/sub/SourceLink";
@@ -41,7 +41,7 @@ export function WikiSource<A extends RecordBase> (props: WikiSourceProps<A>) {
fmap (b => {
const p = SourceLink.A.page (sl)
return `${Book.A.name (b)} ${isPair (p) ? `${fst (p)}${snd (p)}` : p}`
return `${Book.A.name (b)} ${isTuple (p) ? `${fst (p)}${snd (p)}` : p}`
})
))
(available_src)
@@ -1,5 +1,6 @@
import * as React from "react";
import { Either, eitherToMaybe, invertEither, Left, Right } from "../../../Data/Either";
import { Either, invertEither, Left, Right } from "../../../Data/Either";
import { eitherToMaybe } from "../../../Data/Either/Extra";
import { cnst, flip, ident, join } from "../../../Data/Function";
import { fmap, fmapF } from "../../../Data/Functor";
import { rangeN } from "../../../Data/Ix";
@@ -7,10 +7,9 @@ import { all, append, cons, consF, deleteAt, find, findIndex, flength, foldr, im
import { alt_, any, bind, bindF, catMaybes, ensure, fromJust, fromMaybe, fromMaybe_, isJust, Just, liftM2, mapMaybe, Maybe, maybe, maybeRNull, maybeRNullF, maybeToList, maybe_, Nothing } from "../../../Data/Maybe";
import { elems, lookup, lookupF, member, memberF, OrderedMap } from "../../../Data/OrderedMap";
import { difference, fromList, insert, OrderedSet, toList } from "../../../Data/OrderedSet";
import { fst, snd } from "../../../Data/Pair";
import { fromDefault, Record } from "../../../Data/Record";
import { show } from "../../../Data/Show";
import { Pair, Tuple } from "../../../Data/Tuple";
import { fst, Pair, snd, Tuple } from "../../../Data/Tuple";
import { sel1, sel2, sel3 } from "../../../Data/Tuple/Select";
import { upd1, upd2, upd3 } from "../../../Data/Tuple/Update";
import { Sex } from "../../Models/Hero/heroTypeHelpers";
@@ -4,8 +4,8 @@ import { fmap } from "../../../Data/Functor";
import { elemF, intercalate, List, mapAccumL, notNull, notNullStr, subscript, toArray } from "../../../Data/List";
import { bindF, ensure, fromMaybe, fromMaybeR, guard, Just, mapMaybe, Maybe, Nothing, or, thenF } from "../../../Data/Maybe";
import { OrderedMap } from "../../../Data/OrderedMap";
import { Pair, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { Pair, snd } from "../../../Data/Tuple";
import { WikiInfoContainer } from "../../Containers/WikiInfoContainer";
import { ActivatableSkillDependent } from "../../Models/ActiveEntries/ActivatableSkillDependent";
import { HeroModelRecord } from "../../Models/Hero/HeroModel";
+1 -1
View File
@@ -3,8 +3,8 @@ import { isNumber, isString } from "util";
import { fmap, fmapF } from "../../../Data/Functor";
import { consF, imap, notNullStr, subscript, unfoldr } from "../../../Data/List";
import { and, bindF, ensure, isNothing, Just, Maybe, maybe, Nothing } from "../../../Data/Maybe";
import { Pair } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { HeroModelRecord } from "../../Models/Hero/HeroModel";
import { InputTextEvent } from "../../Models/Hero/heroTypeHelpers";
import { Pact } from "../../Models/Hero/Pact";
@@ -7,8 +7,8 @@ import { flength, List, notNullStr } from "../../../Data/List";
import { bindF, ensure, fromJust, isJust, isNothing, Just, liftM3, mapMaybe, Maybe, maybe, maybeToNullable, maybe_, Nothing, or } from "../../../Data/Maybe";
import { adjust, alter, lookup, lookupF, OrderedMap, size } from "../../../Data/OrderedMap";
import { OrderedSet } from "../../../Data/OrderedSet";
import { first, fst, Pair, second, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { first, fst, Pair, second, snd } from "../../../Data/Tuple";
import { Selections as SelectionsInterface } from "../../Models/Hero/heroTypeHelpers";
import { Attribute } from "../../Models/Wiki/Attribute";
import { Culture } from "../../Models/Wiki/Culture";
@@ -3,8 +3,8 @@ import { fmap, fmapF, mapReplace } from "../../../Data/Functor";
import { isList, List, map } from "../../../Data/List";
import { altF_, bind, ensure, Just, mapMaybe, Maybe, maybeToNullable } from "../../../Data/Maybe";
import { lookupF, OrderedMap } from "../../../Data/OrderedMap";
import { fst, Pair, snd } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { fst, Pair, snd } from "../../../Data/Tuple";
import { L10nRecord } from "../../Models/Wiki/L10n";
import { SpecializationSelection } from "../../Models/Wiki/professionSelections/SpecializationSelection";
import { Skill } from "../../Models/Wiki/Skill";
@@ -3,8 +3,8 @@ import { equals } from "../../../../Data/Eq";
import { fmap, fmapF } from "../../../../Data/Functor";
import { filter, find, flength, intercalate, List, map, splitAt } from "../../../../Data/List";
import { fromMaybe, fromMaybeR, Just, Maybe, Nothing } from "../../../../Data/Maybe";
import { fst, snd } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { fst, snd } from "../../../../Data/Tuple";
import { Pet } from "../../../Models/Hero/Pet";
import { Purse } from "../../../Models/Hero/Purse";
import { AttributeCombined, AttributeCombinedA_ } from "../../../Models/View/AttributeCombined";
@@ -3,9 +3,8 @@ import { Textfit } from "react-textfit";
import { fmap, fmapF } from "../../../../Data/Functor";
import { flength, intercalate, List, map, replicateR, subscript, subscriptF, toArray } from "../../../../Data/List";
import { bindF, fromMaybeR, Maybe } from "../../../../Data/Maybe";
import { fst, snd } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { bimap, isTuple } from "../../../../Data/Tuple";
import { bimap, fst, isTuple, snd } from "../../../../Data/Tuple";
import { MeleeWeapon } from "../../../Models/View/MeleeWeapon";
import { L10nRecord } from "../../../Models/Wiki/L10n";
import { ndash } from "../../../Utilities/Chars";
@@ -1,7 +1,7 @@
import * as React from "react";
import { List, map, splitAt, toArray } from "../../../../Data/List";
import { fst, snd } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { fst, snd } from "../../../../Data/Tuple";
import { NumIdName } from "../../../Models/NumIdName";
import { L10nRecord } from "../../../Models/Wiki/L10n";
import { translate } from "../../../Utilities/I18n";
+1 -1
View File
@@ -3,8 +3,8 @@ import { equals } from "../../../Data/Eq";
import { find, List } from "../../../Data/List";
import { bindF, Maybe, maybeRNull } from "../../../Data/Maybe";
import { OrderedMap } from "../../../Data/OrderedMap";
import { Pair } from "../../../Data/Pair";
import { Record } from "../../../Data/Record";
import { Pair } from "../../../Data/Tuple";
import { ActivatableDependent } from "../../Models/ActiveEntries/ActivatableDependent";
import { HeroModel, HeroModelRecord } from "../../Models/Hero/HeroModel";
import { Sex } from "../../Models/Hero/heroTypeHelpers";
@@ -2,8 +2,8 @@ import * as React from "react";
import { List } from "../../../../Data/List";
import { Maybe } from "../../../../Data/Maybe";
import { OrderedMap } from "../../../../Data/OrderedMap";
import { Pair } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { Pair } from "../../../../Data/Tuple";
import { ActivatableDependent } from "../../../Models/ActiveEntries/ActivatableDependent";
import { AttributeCombined } from "../../../Models/View/AttributeCombined";
import { SkillCombined } from "../../../Models/View/SkillCombined";
@@ -2,8 +2,8 @@ import * as React from "react";
import { List, subscriptF } from "../../../../Data/List";
import { bindF, fromMaybeR, Maybe, maybeR } from "../../../../Data/Maybe";
import { lookup, OrderedMap } from "../../../../Data/OrderedMap";
import { Pair } from "../../../../Data/Pair";
import { Record } from "../../../../Data/Record";
import { Pair } from "../../../../Data/Tuple";
import { AttributeCombined } from "../../../Models/View/AttributeCombined";
import { SkillCombined } from "../../../Models/View/SkillCombined";
import { L10nRecord } from "../../../Models/Wiki/L10n";
+253 -11
View File
@@ -1,10 +1,11 @@
import { Either, isEither, Right } from "../Data/Either";
import { Internals } from "../Data/Internals";
import { isList, List, NonEmptyList } from "../Data/List";
import { isMaybe, Just, Maybe } from "../Data/Maybe";
import { Either, isEither, isRight, Right } from "../Data/Either";
import { fromRight_ } from "../Data/Either/Extra";
import { fmap } from "../Data/Functor";
import { consF, fnull, head, isList, List, Nil, NonEmptyList } from "../Data/List";
import { fromJust, isJust, isMaybe, Just, Maybe, Nothing, Some } from "../Data/Maybe";
import { showP } from "../Data/Show";
import { isTagged, Tagged } from "../Data/Tagged";
import { Identity } from "./Monad/Identity";
import { Identity, isIdentity, runIdentity } from "./Monad/Identity";
export type Applicative<A> = Maybe<A>
| List<A>
@@ -12,6 +13,8 @@ export type Applicative<A> = Maybe<A>
| Identity<A>
| Tagged<any, A>
export type ApplicativeName = "Maybe" | "List" | "Either" | "Identity" | "Tagged"
export interface ApplicativeMap<A> {
Maybe: Maybe<A>
List: List<A>
@@ -52,11 +55,9 @@ export const pure: Pure =
return Tagged (x)
}
throw new TypeError (instanceErrorMsg ("pure") (t))
throw new TypeError (applicativeInstanceErrorMsg ("pure") (t))
}
export type ApplicativeName = "Maybe" | "List" | "Either" | "Identity" | "Tagged"
export const typeFromApplicative =
(x: Applicative<any>): ApplicativeName => {
if (isMaybe (x)) {
@@ -71,7 +72,7 @@ export const typeFromApplicative =
return "Either"
}
if (Internals.isIdentity (x)) {
if (isIdentity (x)) {
return "Identity"
}
@@ -79,10 +80,251 @@ export const typeFromApplicative =
return "Tagged"
}
throw new TypeError (instanceErrorMsg ("typeFromApplicative") (x))
throw new TypeError (applicativeInstanceErrorMsg ("typeFromApplicative") (x))
}
const instanceErrorMsg =
interface ApplicativeAp {
<A, B> (fs: List<(x: A) => B>): (xs: List<A>) => List<B>
<E, A, B> (ff: Either<E, (x: A) => B>): (x: Either<E, A>) => Either<E, B>
<A, B> (ff: Identity<(x: A) => B>): (x: Identity<A>) => Identity<B>
<A extends Some, B extends Some> (ff: Maybe<(x: A) => B>): (x: Maybe<A>) => Maybe<B>
}
/**
* `(<*>) :: f (a -> b) -> f a -> f b`
*
* Sequential application.
*/
export const ap: ApplicativeAp =
(ff: Applicative<(x: any) => any>) =>
(x: any): any => {
if (isList (ff)) {
if (isList (x)) {
return fnull (ff) || fnull (x)
? List ()
: mapAp (head (ff)) (ap (ff .xs) (x)) (x)
}
throw new TypeError (applicativeDifferentInstanceErrorMsg ("<*>") (ff) (x))
}
if (isEither (ff)) {
if (isEither (x)) {
return isRight (ff) ? fmap (fromRight_ (ff)) (x) : ff
}
throw new TypeError (applicativeDifferentInstanceErrorMsg ("<*>") (ff) (x))
}
if (isIdentity (ff)) {
if (isIdentity (x)) {
return fmap (runIdentity (ff)) (x)
}
throw new TypeError (applicativeDifferentInstanceErrorMsg ("<*>") (ff) (x))
}
if (isMaybe (ff)) {
if (isMaybe (x)) {
return isJust (ff) ? fmap (fromJust (ff)) (x) : ff
}
throw new TypeError (applicativeDifferentInstanceErrorMsg ("<*>") (ff) (x))
}
throw new TypeError (applicativeInstanceErrorMsg ("<*>") (ff))
}
const mapAp =
<A, B>
(f: (x: A) => B) =>
(xs: List<B>) =>
(x: List<A>): List<B> =>
fnull (x)
? xs
: consF (f (x .x)) (mapAp (f) (xs) (x .xs))
export const Applicative = {
pure,
ap,
}
// ALTERNATIVE
export type Alternative<A> = List<A>
| Maybe<A>
type AlternativeStr = "List" | "Maybe"
interface AlternativeAlt {
<A> (x: List<A>): (y: List<A>) => List<A>
<A extends Some> (x: Maybe<A>): (y: Maybe<A>) => Maybe<A>
}
/**
* `alt :: f a -> f a -> f a`
*
* Returns the first `Alternative` if it is not `empty`, otherwise the second.
*/
export const alt: AlternativeAlt =
(x: any) => (y: any): any => {
if (isList (x)) {
if (isList (y)) {
return fnull (x) ? y : x
}
throw new TypeError (alternativeDifferentInstanceErrorMsg ("<*>") (x) (y))
}
if (isMaybe (x)) {
if (isMaybe (y)) {
return isJust (x) ? x : y
}
throw new TypeError (alternativeDifferentInstanceErrorMsg ("<*>") (x) (y))
}
throw new TypeError (alternativeInstanceErrorMsg ("<*>") (x))
}
interface AlternativeAlt_ {
<A> (x: List<A>): (g: () => List<A>) => List<A>
<A extends Some> (x: Maybe<A>): (g: () => Maybe<A>) => Maybe<A>
}
/**
* `alt' :: f a -> (() -> f a) -> f a`
*
* Returns the first `Alternative` if it is not `empty`, otherwise the second.
*
* Lazy version of `alt`.
*/
export const alt_: AlternativeAlt_ =
(x: any) => (g: () => any): any => {
if (isList (x)) {
return fnull (x) ? g () : x
}
if (isMaybe (x)) {
return isJust (x) ? x : g ()
}
throw new TypeError (alternativeInstanceErrorMsg ("<*>") (x))
}
interface AlternativeAltF {
<A> (y: List<A>): (x: List<A>) => List<A>
<A extends Some> (y: Maybe<A>): (x: Maybe<A>) => Maybe<A>
}
/**
* `altF :: f a -> f a -> f a`
*
* Returns the second `Alternative` if it is not `empty`, otherwise the first.
*
* Flipped version of `alt`.
*/
export const altF: AlternativeAltF = (y: any) => (x: any): any => alt (x) (y)
interface AlternativeAltF_ {
<A> (g: () => List<A>): (x: List<A>) => List<A>
<A extends Some> (g: () => Maybe<A>): (x: Maybe<A>) => Maybe<A>
}
/**
* `altF' :: (() -> f a) -> f a -> f a`
*
* Returns the second `Alternative` if it is not `empty`, otherwise the first.
*
* Flipped version of `alt'`.
*/
export const altF_: AlternativeAltF_ =
(g: () => any) => (x: any): any =>
alt_ (x) (g)
interface AlternativeEmpty {
(t: "List"): Nil
(t: "Maybe"): Nothing
}
/**
* `empty :: f a`
*/
export const empty: AlternativeEmpty =
(t: AlternativeStr): any => {
if (t === "List") {
return List ()
}
if (t === "Maybe") {
return Nothing
}
throw new TypeError (applicativeInstanceErrorMsg ("empty") (t))
}
interface AlternativeGuard {
(t: "List"): (pred: boolean) => List<true>
(t: "Maybe"): (pred: boolean) => Maybe<true>
}
/**
* `guard :: Bool -> Maybe ()`
*
* Conditional failure of Alternative computations. Defined by
* ```haskell
* guard True = pure ()
* guard False = empty
* ```
* In TypeScript, this is not possible, so instead it's
* ```ts
* guard (true) = pure (true)
* guard (false) = empty
* ```
*/
export const guard: AlternativeGuard =
(t: AlternativeStr) =>
(pred: boolean): any =>{
if (t === "List") {
return pred ? pure ("List") <true> (true) : empty ("List")
}
if (t === "Maybe") {
return pred ? pure ("Maybe") <true> (true) : empty ("Maybe")
}
throw new TypeError (applicativeInstanceErrorMsg ("empty") (t))
}
export const Alternative = {
alt,
alt_,
altF,
altF_,
empty,
guard,
}
const applicativeInstanceErrorMsg =
(fname: string) =>
(x: any) =>
`${fname}: missing instance of Applicative\n${showP (x)}`
const applicativeDifferentInstanceErrorMsg =
(fname: string) =>
(x: any) =>
(y: any) =>
`${fname}: different instance of Applicative\n${showP (x)}\nand\n${showP (y)}`
const alternativeInstanceErrorMsg =
(fname: string) =>
(x: any) =>
`${fname}: missing instance of Alternative\n${showP (x)}`
const alternativeDifferentInstanceErrorMsg =
(fname: string) =>
(x: any) =>
(y: any) =>
`${fname}: different instance of Alternative\n${showP (x)}\nand\n${showP (y)}`
+1 -4
View File
@@ -10,10 +10,7 @@
import { pipe } from "../App/Utilities/pipe";
import { Either, Left, Right } from "../Data/Either";
import { ident } from "../Data/Function";
import { Internals } from "../Data/Internals";
import { fromIO } from "../System/IO";
import IO = Internals.IO
import { fromIO, IO } from "../System/IO";
/**
* `catch :: Exception e => IO a -> (e -> IO a) -> IO a`
+368
View File
@@ -0,0 +1,368 @@
/**
* @module Control.Monad
*
* The `Monad` class defines the basic operations over a *monad*, a concept from
* a branch of mathematics known as *category theory*. From the perspective of a
* Haskell programmer, however, it is best to think of a monad as an
* *abstract datatype* of actions. Haskell's `do` expressions provide a
* convenient syntax for writing monadic expressions.
*
* @author Lukas Obermann
*/
import { pipe } from "../App/Utilities/pipe";
import { Either, isEither, isRight, Right } from "../Data/Either";
import { ident } from "../Data/Function";
import { fmap } from "../Data/Functor";
import { append, cons, fnull, head, isList, List, tail } from "../Data/List";
import { isJust, isMaybe, Just, Maybe, Some } from "../Data/Maybe";
import { showP } from "../Data/Show";
import { empty, pure } from "./Applicative";
export type Monad<A> = Either<any, A>
| List<A>
| Maybe<A>
type MonadStr = "Either" | "List" | "Maybe"
interface MonadBind {
<E, A> (x: Either<E, A>): <B> (f: (x: A) => Either<E, B>) => Either<E, B>
<A> (xs: List<A>): <B> (f: (x: A) => List<B>) => List<B>
<A extends Some> (x: Maybe<A>): <B extends Some> (f: (x: A) => Maybe<B>) => Maybe<B>
}
/**
* `(>>=) :: Monad m => m a -> (a -> m b) -> m b`
*/
export const bind: MonadBind =
<A> (x: Monad<A>) => (f: (x: A) => any): any => {
if (isList (x)) {
return fnull (x) ? empty ("List") : append (f (x .x)) (bind<A> (x .xs) (f))
}
if (isEither (x)) {
return isRight (x) ? f (x .value) : x
}
if (isMaybe (x)) {
return isJust (x) ? f (x .value) : x
}
throw new TypeError (instanceErrorMsg (">>=") (x))
}
interface MonadBindF {
<E, A, B> (f: (x: A) => Either<E, B>): (x: Either<E, A>) => Either<E, B>
<A, B> (f: (x: A) => List<B>): (xs: List<A>) => List<B>
<A extends Some, B extends Some> (f: (x: A) => Maybe<B>): (x: Maybe<A>) => Maybe<B>
}
/**
* `(=<<) :: Monad m => (a -> m b) -> m a -> m b`
*/
export const bindF: MonadBindF =
<A> (f: (x: A) => any) => (x: any): any => bind<A> (x) (f)
interface MonadThen {
<E> (x: Either<E, any>): <A> (x: Either<E, A>) => Either<E, A>
(xs: List<any>): <A> (ys: List<A>) => List<A>
(x: Maybe<any>): <A extends Some> (y: Maybe<A>) => Maybe<A>
}
/**
* `(>>) :: Monad m => m a -> m b -> m b`
*
* Sequentially compose two actions, discarding any value produced by the
* first, like sequencing operators (such as the semicolon) in imperative
* languages.
*
* ```a >> b = a >>= \ _ -> b```
*/
export const then: MonadThen =
(x: any) => (y: any): any =>
bind<any> (x) (_ => y)
interface MonadKleisli {
<E, A, B, C>
(f: (x: A) => Either<E, B>):
(g: (x: B) => Either<E, C>) =>
(x: A) => Either<E, C>
<A, B, C>
(f: (x: A) => List<B>):
(g: (x: B) => List<C>) =>
(x: A) => List<C>
<A extends Some, B extends Some, C extends Some>
(f: (x: A) => Maybe<B>):
(g: (x: B) => Maybe<C>) =>
(x: A) => Maybe<C>
}
/**
* `(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c`
*
* Left-to-right Kleisli composition of monads.
*/
export const kleisli: MonadKleisli =
(f: (x: any) => any) =>
(g: (x: any) => any) =>
pipe (f, bindF (g) as (x: any) => any)
interface MonadJoin {
<E, A> (x: Either<E, Either<E, A>>): Either<E, A>
<A> (xss: List<List<A>>): List<A>
<A extends Some> (x: Maybe<Maybe<A>>): Maybe<A>
}
/**
* `join :: Monad m => m (m a) -> m a`
*
* The `join` function is the conventional monad join operator. It is used to
* remove one level of monadic structure, projecting its bound argument into the
* outer level.
*/
export const join: MonadJoin = bindF<any, any> (ident) as (x: any) => any
interface MonadMapM {
(t: "Either"): <E, A, B> (f: (x: A) => Either<E, B>) => (xs: List<A>) => Either<E, List<B>>
(t: "List"): <A, B> (f: (x: A) => List<B>) => (xs: List<A>) => List<List<B>>
(t: "Maybe"): <A, B extends Some> (f: (x: A) => Maybe<B>) => (xs: List<A>) => Maybe<List<B>>
}
/**
* `mapM :: Monad m => (a -> m b) -> [a] -> m [b]`
*
* Map each element of a structure to a monadic action, evaluate these actions
* from left to right, and collect the results.
*
* In case of `Maybe`, if the function returns a `Nothing`, it is immediately
* returned by the function. If `f` did not return any `Nothing`, the list of
* unwrapped return values is returned as a `Just`. If `xs` is empty,
* `Just []` is returned.
*/
export const mapM: MonadMapM =
(t: MonadStr) =>
(f: (x: any) => any) =>
(xs: List<any>): any => {
if (t === "List") {
return sequence ("List") (fmap (f) (xs))
}
if (t === "Either") {
return sequence ("Either") (fmap (f) (xs))
}
if (t === "Maybe") {
return sequence ("Maybe") (fmap (f) (xs))
}
throw new TypeError (instanceErrorMsg ("mapM") (t))
}
interface MonadSequence {
(t: "Either"): <E, A> (xs: List<Either<E, A>>) => Either<E, List<A>>
(t: "List"): <A> (xs: List<List<A>>) => List<List<A>>
(t: "Maybe"): <A extends Some> (xs: List<Maybe<A>>) => Maybe<List<A>>
}
/**
* `sequence :: [m a] -> m [a]`
*
* Evaluate each monadic action in the structure from left to right, and collect
* the results.
*
* ```haskell
* sequence [] = return []
* sequence (m:ms) = m >>= (\x -> sequence ms >>= (\xs -> return $ x:xs))
* ```
*/
export const sequence: MonadSequence =
(t: MonadStr) =>
(xs: List<any>): any => {
if (t === "List") {
if (fnull (xs)) {
return pure ("List") (empty ("List"))
}
const m = head (xs)
const ms = tail (xs)
return bind (m as List<any>)
(x => bind (sequence ("List") (ms))
(zs => pure ("List") (cons (zs) (x))))
}
if (t === "Either") {
if (fnull (xs)) {
return Right (empty ("List"))
}
const m = head (xs)
const ms = tail (xs)
return bind (m as Either<any, any>)
(x => bind (sequence ("Either") (ms))
(zs => Right (cons (zs) (x))))
}
if (t === "Maybe") {
if (fnull (xs)) {
return Just (empty ("List"))
}
const m = head (xs)
const ms = tail (xs)
return bind (m as Maybe<any>)
(x => bind (sequence ("Maybe") (ms))
(zs => Just (cons (zs) (x))))
}
throw new TypeError (instanceErrorMsg ("sequence") (t))
}
interface MonadLiftM2<A1, A2, B> {
(x1: List<A1>):
(x2: List<A2>) => List<B>
<E>
(x1: Either<E, A1>):
(x2: Either<E, A2>) => Either<E, B>
(x1: Maybe<A1>):
(x2: Maybe<A2>) => Maybe<B>
}
/**
* `liftM2 :: Monad m => (a1 -> a2 -> r) -> Maybe a1 -> Maybe a2 -> Maybe r`
*
* Promote a function to a monad, scanning the monadic arguments from left to
* right.
*/
export const liftM2 =
<A1, A2, B>
(f: (a1: A1) => (a2: A2) => B): MonadLiftM2<A1, A2, B> =>
(x1: any) =>
(x2: any): any =>
bind (x1) (a1 => fmap (f (a1 as A1)) (x2) as any)
interface MonadLiftM3<A1, A2, A3, B> {
(x1: List<A1>):
(x2: List<A2>) =>
(x3: List<A3>) => List<B>
<E>
(x1: Either<E, A1>):
(x2: Either<E, A2>) =>
(x3: Either<E, A3>) => Either<E, B>
(x1: Maybe<A1>):
(x2: Maybe<A2>) =>
(x3: Maybe<A3>) => Maybe<B>
}
/**
* `liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r`
*
* Promote a function to a monad, scanning the monadic arguments from left to
* right.
*/
export const liftM3 =
<A1, A2, A3, B>
(f: (a1: A1) => (a2: A2) => (a3: A3) => B): MonadLiftM3<A1, A2, A3, B> =>
(x1: any) =>
(x2: any) =>
(x3: any): any =>
bind (x1) (a1 => liftM2 (f (a1 as A1)) (x2) (x3) as any)
interface MonadLiftM4<A1, A2, A3, A4, B> {
(x1: List<A1>):
(x2: List<A2>) =>
(x3: List<A3>) =>
(x4: List<A4>) => List<B>
<E>
(x1: Either<E, A1>):
(x2: Either<E, A2>) =>
(x3: Either<E, A3>) =>
(x4: Either<E, A4>) => Either<E, B>
(x1: Maybe<A1>):
(x2: Maybe<A2>) =>
(x3: Maybe<A3>) =>
(x4: Maybe<A4>) => Maybe<B>
}
/**
* ```haskell
* liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r)
* -> m a1
* -> m a2
* -> m a3
* -> m a4
* -> m r
* ```
*
* Promote a function to a monad, scanning the monadic arguments from left to
* right.
*/
export const liftM4 =
<A1, A2, A3, A4, B>
(f: (a1: A1) => (a2: A2) => (a3: A3) => (a4: A4) => B): MonadLiftM4<A1, A2, A3, A4, B> =>
(x1: any) =>
(x2: any) =>
(x3: any) =>
(x4: any): any =>
bind (x1) (a1 => liftM3 (f (a1 as A1)) (x2) (x3) (x4) as any)
interface MonadLiftM5<A1, A2, A3, A4, A5, B> {
(x1: List<A1>):
(x2: List<A2>) =>
(x3: List<A3>) =>
(x4: List<A4>) =>
(x5: List<A5>) => List<B>
<E>
(x1: Either<E, A1>):
(x2: Either<E, A2>) =>
(x3: Either<E, A3>) =>
(x4: Either<E, A4>) =>
(x5: Either<E, A5>) => Either<E, B>
(x1: Maybe<A1>):
(x2: Maybe<A2>) =>
(x3: Maybe<A3>) =>
(x4: Maybe<A4>) =>
(x5: Maybe<A5>) => Maybe<B>
}
/**
* ```haskell
* liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r)
* -> m a1
* -> m a2
* -> m a3
* -> m a4
* -> m a5
* -> m r
* ```
*
* Promote a function to a monad, scanning the monadic arguments from left to
* right.
*/
export const liftM5 =
<A1, A2, A3, A4, A5, B>
(f: (a1: A1) => (a2: A2) => (a3: A3) => (a4: A4) => (a5: A5) => B):
MonadLiftM5<A1, A2, A3, A4, A5, B> =>
(x1: any) =>
(x2: any) =>
(x3: any) =>
(x4: any) =>
(x5: any): any =>
bind (x1) (a1 => liftM4 (f (a1 as A1)) (x2) (x3) (x4) (x5) as any)
const instanceErrorMsg =
(fname: string) =>
(x: any) =>
`${fname}: missing instance of Monad\n${showP (x)}`
+38 -3
View File
@@ -12,11 +12,39 @@
* @author Lukas Obermann
*/
import { Internals } from "../../Data/Internals";
// PROTOTYPE
interface IdentityPrototype {
readonly isIdentity: true
}
const IdentityPrototype =
Object.freeze<IdentityPrototype> ({
isIdentity: true,
})
// CONSTRUCTOR
export import Identity = Internals.Identity
export interface Identity<A> extends IdentityPrototype {
readonly value: A
}
/**
* `Identity :: a -> Identity a`
*/
export const Identity =
<A>
(x: A): Identity<A> =>
Object.create (
IdentityPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
/**
* `runIdentity :: Identity a -> a`
@@ -26,4 +54,11 @@ export const runIdentity = <A> (x: Identity<A>): A => x .value
// CUSTOM IDENTITY FUNCTIONS
export import isIdentity = Internals.isIdentity
/**
* `isIdentity :: a -> Bool`
*
* The `isIdentity` function returns `True` if its argument is an `Identity`.
*/
export const isIdentity =
(x: any): x is Identity<any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === IdentityPrototype
+162 -189
View File
@@ -16,26 +16,146 @@ import { ifElse } from "../App/Utilities/ifElse";
import { pipe } from "../App/Utilities/pipe";
import { ident } from "./Function";
import { fmap, fmapF } from "./Functor";
import { Internals } from "./Internals";
import { cons, consF, List } from "./List";
import { fromJust, isJust, Just, Maybe, Nothing, Some } from "./Maybe";
import { Just, Maybe, Nothing, Some } from "./Maybe";
import { Pair, Tuple } from "./Tuple";
export import Left = Internals.Left
export import Right = Internals.Right
export import isLeft = Internals.isLeft
export import isRight = Internals.isRight
// PROTOTYPES
interface LeftPrototype {
readonly isLeft: true
readonly isRight: false
}
const LeftPrototype =
Object.freeze<LeftPrototype> ({
isLeft: true,
isRight: false,
})
interface RightPrototype {
readonly isLeft: false
readonly isRight: true
}
const RightPrototype: RightPrototype =
Object.freeze<RightPrototype> ({
isLeft: false,
isRight: true,
})
// CONSTRUCTORS
export type Either<A, B> = Left<A> | Right<B>
// @module Data.Either.Extra
//
// This module extends `Data.Either` with extra operations, particularly to
// quickly extract from inside an `Either`. Some of these operations are
// partial, and should be used with care in production-quality code.
//
// @author Lukas Obermann
// @see Data.Either
export interface Left<A> extends LeftPrototype {
readonly value: A
}
/**
* `Left :: a -> Either a b`
*
* Creates a new `Left` from the passed value.
*/
export const Left =
<A>
(x: A): Left<A> =>
Object.create (
LeftPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
export interface Right<B> extends RightPrototype {
readonly value: B
readonly prototype: RightPrototype
}
/**
* `Right :: b -> Either a b`
*
* Creates a new `Right` from the passed value.
*/
export const Right =
<B>
(x: B): Right<B> =>
Object.create (
RightPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
// EITHER FUNCTIONS
/**
* `either :: (a -> c) -> (b -> c) -> Either a b -> c`
*
* Case analysis for the `Either` type. If the value is `Left a`, apply the
* first function to `a` if it is `Right b`, apply the second function to `b`.
*/
export const either =
<A, B, C>
(fLeft: (l: A) => C) =>
(fRight: (r: B) => C) =>
(x: Either<A, B>): C =>
isRight (x) ? fRight (x .value) : fLeft (x .value)
/**
* `lefts :: [Either a b] -> [a]`
*
* Extracts from a list of `Either` all the `Left` elements. All the `Left`
* elements are extracted in order.
*/
export const lefts =
<A, B> (xs: List<Either<A, B>>): List<A> =>
List.foldr<Either<A, B>, List<A>> (x => acc => isLeft (x)
? cons (acc) (x .value)
: acc)
(List.empty)
(xs)
/**
* `rights :: [Either a b] -> [b]`
*
* Extracts from a list of `Either` all the `Right` elements. All the `Right`
* elements are extracted in order.
*/
export const rights =
<A, B> (xs: List<Either<A, B>>): List<B> =>
List.foldr<Either<A, B>, List<B>> (x => acc => isRight (x)
? cons (acc) (x .value)
: acc)
(List.empty)
(xs)
/**
* `isLeft :: Either a b -> Bool`
*
* Return `True` if the given value is a `Left`-value, `False` otherwise.
*/
export const isLeft =
<A, B> (x: Either<A, B>): x is Left<A> =>
Object.getPrototypeOf (x) === LeftPrototype
/**
* `isRight :: Either a b -> Bool`
*
* Return `True` if the given value is a `Right`-value, `False` otherwise.
*/
export const isRight =
<A, B> (x: Either<A, B>): x is Right<B> =>
Object.getPrototypeOf (x) === RightPrototype
/**
* `fromLeft :: a -> Either a b -> a`
@@ -67,107 +187,20 @@ export const fromRight =
isRight (x) ? x .value : def
/**
* `fromEither :: Either a a -> a`
* `partitionEithers :: [Either a b] -> ([a], [b])`
*
* Pull the value out of an `Either` where both alternatives have the same type.
*
* `\x -> fromEither (Left x ) == x`
* `\x -> fromEither (Right x) == x`
* Partitions a list of `Either` into two lists. All the `Left` elements are
* extracted, in order, to the first component of the output. Similarly the
* `Right` elements are extracted to the second component of the output.
*/
export const fromEither =
<A>
(x: Either<A, A>): A =>
isRight (x) ? x .value : x .value
/**
* `fromLeft' :: Either l r -> l`
*
* The `fromLeft'` function extracts the element out of a `Left` and throws an
* error if its argument is `Right`. Much like `fromJust`, using this function
* in polished code is usually a bad idea.
*
* `\x -> fromLeft' (Left x) == x`
* `\x -> fromLeft' (Right x) == undefined`
*
* @throws TypeError
*/
export const fromLeft_ =
<L>
(x: Left<L>): L => {
if (isLeft (x)) {
return x .value
}
throw new TypeError (`Cannot extract a Left value out of ${x}.`)
}
/**
* `fromRight' :: Either l r -> r`
*
* The `fromRight'` function extracts the element out of a `Right` and throws an
* error if its argument is `Left`. Much like `fromJust`, using this function
* in polished code is usually a bad idea.
*
* `\x -> fromRight' (Right x) == x`
* `\x -> fromRight' (Left x) == undefined`
*
* @throws TypeError
*/
export const fromRight_ =
<R>
(x: Right<R>): R => {
if (isRight (x)) {
return x .value
}
throw new TypeError (`Cannot extract a Right value out of ${x}.`)
}
/**
* `eitherToMaybe :: Either a b -> Maybe b`
*
* Given an `Either`, convert it to a `Maybe`, where `Left` becomes `Nothing`.
*
* `\x -> eitherToMaybe (Left x) == Nothing`
* `\x -> eitherToMaybe (Right x) == Just x`
*/
export const eitherToMaybe =
<B>
(x: Either<any, B>): Maybe<B> =>
isRight (x) ? Just (x .value) : Nothing
/**
* `maybeToEither :: a -> Maybe b -> Either a b`
*
* Given a `Maybe`, convert it to an `Either`, providing a suitable value for
* the `Left` should the value be `Nothing`.
*
* `\a b -> maybeToEither a (Just b) == Right b`
* `\a -> maybeToEither a Nothing == Left a`
*/
export const maybeToEither =
<A>
(left: A) =>
<B> (x: Maybe<B>): Either<A, B> =>
isJust (x) ? Right (fromJust (x)) : Left (left)
/**
* `maybeToEither' :: (() -> a) -> Maybe b -> Either a b`
*
* Given a `Maybe`, convert it to an `Either`, providing a suitable value for
* the `Left` should the value be `Nothing`.
*
* `\a b -> maybeToEither a (Just b) == Right b`
* `\a -> maybeToEither a Nothing == Left a`
*
* Lazy version of `maybeToEither`.
*/
export const maybeToEither_ =
<A>
(left: () => A) =>
<B>
(x: Maybe<B>): Either<A, B> =>
isJust (x) ? Right (fromJust (x)) : Left (left ())
export const partitionEithers =
<A, B> (xs: List<Either<A, B>>): Pair<List<A>, List<B>> =>
List.foldr<Either<A, B>, Pair<List<A>, List<B>>>
(x => isRight (x)
? Tuple.second (consF (x .value))
: Tuple.first (consF (x .value)))
(Pair<List<A>, List<B>> (List.empty, List.empty))
(xs)
// BIFUNCTOR
@@ -305,7 +338,7 @@ export const mapM =
(isLeft)
<Either<E, List<B>>>
(ident)
(y => second (consF (fromRight_ (y)))
(y => second (consF (y .value))
(mapM (f) (xs .xs)))
(f (xs .x))
@@ -595,69 +628,16 @@ export const lte =
|| isLeft (m1) && isLeft (m2) && m2 .value <= m1 .value
// EITHER FUNCTIONS (PART 2)
/**
* `either :: (a -> c) -> (b -> c) -> Either a b -> c`
*
* Case analysis for the `Either` type. If the value is `Left a`, apply the
* first function to `a` if it is `Right b`, apply the second function to `b`.
*/
export const either =
<A, B, C>
(fLeft: (l: A) => C) =>
(fRight: (r: B) => C) =>
(x: Either<A, B>): C =>
isRight (x) ? fRight (x .value) : fLeft (x .value)
/**
* `lefts :: [Either a b] -> [a]`
*
* Extracts from a list of `Either` all the `Left` elements. All the `Left`
* elements are extracted in order.
*/
export const lefts =
<A, B> (xs: List<Either<A, B>>): List<A> =>
List.foldr<Either<A, B>, List<A>> (x => acc => isLeft (x)
? cons (acc) (x .value)
: acc)
(List.empty)
(xs)
/**
* `rights :: [Either a b] -> [b]`
*
* Extracts from a list of `Either` all the `Right` elements. All the `Right`
* elements are extracted in order.
*/
export const rights =
<A, B> (xs: List<Either<A, B>>): List<B> =>
List.foldr<Either<A, B>, List<B>> (x => acc => isRight (x)
? cons (acc) (x .value)
: acc)
(List.empty)
(xs)
/**
* `partitionEithers :: [Either a b] -> ([a], [b])`
*
* Partitions a list of `Either` into two lists. All the `Left` elements are
* extracted, in order, to the first component of the output. Similarly the
* `Right` elements are extracted to the second component of the output.
*/
export const partitionEithers =
<A, B> (xs: List<Either<A, B>>): Pair<List<A>, List<B>> =>
List.foldr<Either<A, B>, Pair<List<A>, List<B>>>
(x => isRight (x)
? Tuple.second (consF (x .value))
: Tuple.first (consF (x .value)))
(Pair<List<A>, List<B>> (List.empty, List.empty))
(xs)
// CUSTOM FUNCTIONS
export import isEither = Internals.isEither
/**
* `isEither :: a -> Bool`
*
* Return `True` if the given value is an `Either`.
*/
export const isEither =
(x: any): x is Either<any, any> =>
typeof x === "object" && x !== null && (isLeft (x) || isRight (x))
/**
* `imapM :: (Int -> a -> Either e b) -> [a] -> Either e [b]`
@@ -685,7 +665,7 @@ const imapMIndex =
(isLeft)
<Either<E, List<B>>>
(ident)
(y => second (consF (fromRight_ (y)))
(y => second (consF (y .value))
(imapMIndex (i + 1) (f) (xs .xs)))
(f (i) (xs .x))
@@ -711,14 +691,14 @@ export const Either = {
Left,
Right,
isLeft,
isRight,
either,
lefts,
rights,
fromLeft,
fromRight,
fromEither,
fromLeft_,
fromRight_,
eitherToMaybe,
maybeToEither,
maybeToEither_,
partitionEithers,
bimap,
first,
@@ -758,13 +738,6 @@ export const Either = {
gte,
lte,
isLeft,
isRight,
either,
lefts,
rights,
partitionEithers,
isEither,
imapM,
invertEither,
+119
View File
@@ -0,0 +1,119 @@
/**
* @module Data.Either.Extra
*
* This module extends `Data.Either` with extra operations, particularly to
* quickly extract from inside an `Either`. Some of these operations are
* partial, and should be used with care in production-quality code.
*
* @author Lukas Obermann
* @see Data.Either
*/
import { Either, isLeft, isRight, Left, Right } from "../Either";
import { fromJust, isJust, Just, Maybe, Nothing } from "../Maybe";
export { fromLeft, fromRight } from "../Either";
export { isLeft, isRight };
/**
* `fromEither :: Either a a -> a`
*
* Pull the value out of an `Either` where both alternatives have the same type.
*
* `\x -> fromEither (Left x ) == x`
* `\x -> fromEither (Right x) == x`
*/
export const fromEither =
<A>
(x: Either<A, A>): A =>
isRight (x) ? x .value : x .value
/**
* `fromLeft' :: Either l r -> l`
*
* The `fromLeft'` function extracts the element out of a `Left` and throws an
* error if its argument is `Right`. Much like `fromJust`, using this function
* in polished code is usually a bad idea.
*
* `\x -> fromLeft' (Left x) == x`
* `\x -> fromLeft' (Right x) == undefined`
*
* @throws TypeError
*/
export const fromLeft_ =
<L>
(x: Left<L>): L => {
if (isLeft (x)) {
return x .value
}
throw new TypeError (`Cannot extract a Left value out of ${x}.`)
}
/**
* `fromRight' :: Either l r -> r`
*
* The `fromRight'` function extracts the element out of a `Right` and throws an
* error if its argument is `Left`. Much like `fromJust`, using this function
* in polished code is usually a bad idea.
*
* `\x -> fromRight' (Right x) == x`
* `\x -> fromRight' (Left x) == undefined`
*
* @throws TypeError
*/
export const fromRight_ =
<R>
(x: Right<R>): R => {
if (isRight (x)) {
return x .value
}
throw new TypeError (`Cannot extract a Right value out of ${x}.`)
}
/**
* `eitherToMaybe :: Either a b -> Maybe b`
*
* Given an `Either`, convert it to a `Maybe`, where `Left` becomes `Nothing`.
*
* `\x -> eitherToMaybe (Left x) == Nothing`
* `\x -> eitherToMaybe (Right x) == Just x`
*/
export const eitherToMaybe =
<B>
(x: Either<any, B>): Maybe<B> =>
isRight (x) ? Just (x .value) : Nothing
/**
* `maybeToEither :: a -> Maybe b -> Either a b`
*
* Given a `Maybe`, convert it to an `Either`, providing a suitable value for
* the `Left` should the value be `Nothing`.
*
* `\a b -> maybeToEither a (Just b) == Right b`
* `\a -> maybeToEither a Nothing == Left a`
*/
export const maybeToEither =
<A>
(left: A) =>
<B> (x: Maybe<B>): Either<A, B> =>
isJust (x) ? Right (fromJust (x)) : Left (left)
/**
* `maybeToEither' :: (() -> a) -> Maybe b -> Either a b`
*
* Given a `Maybe`, convert it to an `Either`, providing a suitable value for
* the `Left` should the value be `Nothing`.
*
* `\a b -> maybeToEither a (Just b) == Right b`
* `\a -> maybeToEither a Nothing == Left a`
*
* Lazy version of `maybeToEither`.
*/
export const maybeToEither_ =
<A>
(left: () => A) =>
<B>
(x: Maybe<B>): Either<A, B> =>
isJust (x) ? Right (fromJust (x)) : Left (left ())
+33 -45
View File
@@ -4,26 +4,14 @@
* @author Lukas Obermann
*/
import { Internals } from "./Internals";
import { isEither, isRight } from "./Either";
import { fnull, isList } from "./List";
import { isJust, isMaybe, isNothing, Maybe, Some } from "./Maybe";
import { isOrderedMap, OrderedMap } from "./OrderedMap";
import { all, isOrderedSet, member, OrderedSet } from "./OrderedSet";
import { isRecord, Record } from "./Record";
import { show } from "./Show";
import Some = Internals.Some
import Maybe = Internals.Maybe
import Record = Internals.Record
import OrderedMap = Internals.OrderedMap
import OrderedSet = Internals.OrderedSet
const flengthMap = (xs: OrderedMap<any, any>): number => xs .value .size
const flength = (xs: OrderedSet<any>): number => xs .value .size
export const elem =
<A> (e: A) => (xs: OrderedSet<A>): boolean =>
[...xs .value] .some (equals (e))
export const all =
<A> (f: (x: A) => boolean) => (xs: OrderedSet<A>): boolean =>
[...xs .value] .every (f)
import { isTuple } from "./Tuple";
/**
* `(==) :: a -> a -> Bool`
@@ -37,35 +25,35 @@ export const equals =
return false
}
if (Internals.isMaybe (x1)) {
return Internals.isMaybe (x2)
if (isMaybe (x1)) {
return isMaybe (x2)
&& (
Internals.isNothing (x1) && Internals.isNothing (x2 as unknown as Maybe<any>)
|| Internals.isJust (x1) && Internals.isJust (x2) && equals (x1 .value) (x2 .value)
isNothing (x1) && isNothing (x2 as unknown as Maybe<any>)
|| isJust (x1) && isJust (x2) && equals (x1 .value) (x2 .value)
)
}
if (Internals.isEither (x1)) {
return Internals.isEither (x2)
&& Internals.isRight (x1) === Internals.isRight (x2)
if (isEither (x1)) {
return isEither (x2)
&& isRight (x1) === isRight (x2)
&& equals (x1 .value) (x2 .value)
}
if (Internals.isList (x1)) {
if (isList (x1)) {
const equalsCons =
(xs1: any, xs2: any): boolean =>
Internals.isNil (xs1)
&& Internals.isNil (xs2)
|| !Internals.isNil (xs1)
&& !Internals.isNil (xs2)
fnull (xs1)
&& fnull (xs2)
|| !fnull (xs1)
&& !fnull (xs2)
&& equals (xs1 .x) (xs2 .x)
&& equalsCons (xs1 .xs, xs2 .xs)
return Internals.isList (x2) && equalsCons (x1, x2)
return isList (x2) && equalsCons (x1, x2)
}
if (Internals.isTuple (x1)) {
if (Internals.isTuple (x2) && x1 .length === x2 .length) {
if (isTuple (x1)) {
if (isTuple (x2) && x1 .length === x2 .length) {
for (let i = 0; i < x1 .length; i++) {
const equal = equals (x1 .values [i]) (x2 .values [i])
@@ -80,24 +68,24 @@ export const equals =
return false
}
if (Internals.isOrderedSet (x1)) {
if (Internals.isOrderedSet (x2)) {
if (isOrderedSet (x1)) {
if (isOrderedSet (x2)) {
const firstValues = [...x1]
const secondValues = [...x2]
return flength (x1) === flength (x2)
return OrderedSet.flength (x1) === OrderedSet.flength (x2)
&& firstValues .every ((e, i) => equals (e) (secondValues [i]))
}
return false
}
if (Internals.isOrderedMap (x1)) {
if (Internals.isOrderedMap (x2)) {
if (isOrderedMap (x1)) {
if (isOrderedMap (x2)) {
const firstValues = [...x1]
const secondValues = [...x2]
return flengthMap (x1) === flengthMap (x2)
return OrderedMap.flength (x1) === OrderedMap.flength (x2)
&& firstValues .every (
([k, v], i) => {
const second = secondValues [i]
@@ -110,11 +98,11 @@ export const equals =
return false
}
if (Internals.isRecord (x1)) {
if (Internals.isRecord (x2)) {
return flength (x1 .keys) === flength (x2 .keys)
if (isRecord (x1)) {
if (isRecord (x2)) {
return OrderedSet.flength (x1 .keys) === OrderedSet.flength (x2 .keys)
&& all
(key => elem (key) (x2 .keys)
(key => member (key) (x2 .keys)
&& equals (getRecordField<typeof x1["defaultValues"]>
(key as string)
(x1))
@@ -176,7 +164,7 @@ export const notEquals =
!equals (m1) (m2)
const getRecordField = <A> (key: keyof A) => (r: Record<A>) => {
if (elem (key as string) (r .keys)) {
if (member (key as string) (r .keys)) {
const specifiedValue = r .values [key]
// tslint:disable-next-line: strict-type-predicates
+26 -32
View File
@@ -8,23 +8,17 @@
*/
import { pipe } from "../App/Utilities/pipe";
import { Identity, runIdentity } from "../Control/Monad/Identity";
import { Identity, isIdentity, runIdentity } from "../Control/Monad/Identity";
import { IO, isIO } from "../System/IO";
import { Either, isEither, isLeft, Left, Right } from "./Either";
import { cnst } from "./Function";
import { Const } from "./Functor/Const";
import { Internals } from "./Internals";
import { Const, isConst } from "./Functor/Const";
import { consF, fnull, isList, List, NonEmptyList } from "./List";
import { isMarket, Market } from "./Market";
import { Some } from "./Maybe";
import { show, showP } from "./Show";
import { Pair } from "./Tuple";
import Just = Internals.Just
import Maybe = Internals.Maybe
import Either = Internals.Either
import Right = Internals.Right
import List = Internals.List
import IO = Internals.IO
import OrderedMap = Internals.OrderedMap
import mapFromArray = Internals.mapFromArray
import { isMaybe, isNothing, Just, Maybe, Some } from "./Maybe";
import { fromArray, isOrderedMap, OrderedMap } from "./OrderedMap";
import { showP } from "./Show";
import { isTuple, Pair } from "./Tuple";
export type Functor<A> = Const<A, any>
| Either<any, A>
@@ -60,31 +54,31 @@ export const fmap =
(f: (x: A) => B): FunctorMap<A, B> =>
// tslint:disable-next-line: cyclomatic-complexity
(x: Functor<any>): any => {
if (Internals.isList (x)) {
if (Internals.isNil (x)) {
return Internals.Nil
if (isList (x)) {
if (fnull (x)) {
return List ()
}
const nextElement = fmap (f) ((x as Internals.Cons<A>) .xs)
const nextValue = f ((x as Internals.Cons<A>) .x)
const nextElement = fmap (f) ((x as NonEmptyList<A>) .xs)
const nextValue = f ((x as NonEmptyList<A>) .x)
if (nextValue === x .x && nextElement === x .xs) {
return x
}
return Internals.Cons (nextValue, nextElement)
return consF (nextValue) (nextElement)
}
if (Internals.isOrderedMap (x)) {
return mapFromArray (show) ([...x .value] .map (([k, a]) => [k, f (a)] as [any, B]))
if (isOrderedMap (x)) {
return fromArray ([...x .value] .map (([k, a]) => [k, f (a)] as [any, B]))
}
if (Internals.isConst (x)) {
if (isConst (x)) {
return x
}
if (Internals.isEither (x)) {
if (Internals.isLeft (x)) {
if (isEither (x)) {
if (isLeft (x)) {
return x
}
@@ -97,7 +91,7 @@ export const fmap =
return Right (nextValue)
}
if (Internals.isIdentity (x)) {
if (isIdentity (x)) {
const nextValue = f (runIdentity (x))
if (nextValue === runIdentity (x)) {
@@ -107,14 +101,14 @@ export const fmap =
return Identity (nextValue)
}
if (Internals.isIO (x)) {
if (isIO (x)) {
const res = x .f ()
return IO (() => res .then (f))
}
if (Internals.isMaybe (x)) {
if (Internals.isNothing (x)) {
if (isMaybe (x)) {
if (isNothing (x)) {
return x
}
@@ -127,7 +121,7 @@ export const fmap =
return Just (nextValue)
}
if (Internals.isTuple (x) && x .length === 2) {
if (isTuple (x) && x .length === 2) {
const nextValue = f (x .values [1])
if (nextValue === x .values [1]) {
@@ -143,7 +137,7 @@ export const fmap =
if (isMarket (x)) {
return Market (pipe (x.to, f))
(pipe (x.fro, e => Internals.isLeft (e) ? Internals.Left (f (e .value)) : e))
(pipe (x.fro, e => isLeft (e) ? Left (f (e .value)) : e))
}
throw new TypeError (instanceErrorMsg ("fmap") (x))
+42 -3
View File
@@ -7,11 +7,42 @@
* @author Lukas Obermann
*/
import { Internals } from "../Internals";
// PROTOTYPE
interface ConstPrototype {
readonly isConst: true
}
const ConstPrototype =
Object.freeze<ConstPrototype> ({
isConst: true,
})
// CONSTRUCTOR
export import Const = Internals.Const
export interface Const<A, B> extends ConstPrototype {
readonly value: A
/**
* No actual field!
*/
readonly phantom: B
}
/**
* `Const :: a -> Const a b`
*/
export const Const =
<A, B>
(x: A): Const<A, B> =>
Object.create (
ConstPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
/**
* `getConst :: Const a b -> a`
@@ -21,4 +52,12 @@ export const getConst = <A, B> (x: Const<A, B>): A => x .value
// CUSTOM CONST FUNCTIONS
export import isConst = Internals.isConst
/**
* `isConst :: a -> Bool`
*
* The `isConst` function returns `True` if its argument is a `Const`.
*/
export const isConst =
(x: any): x is Const<any, any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === ConstPrototype
+1 -1
View File
@@ -7,7 +7,7 @@ import { List } from "../List";
import { Market } from "../Market";
import { Maybe } from "../Maybe";
import { OrderedMap } from "../OrderedMap";
import { Pair } from "../Pair";
import { Pair } from "../Tuple";
import { Const } from "./Const";
type FunctorMap2<A, B, C> =
+1 -1
View File
@@ -9,8 +9,8 @@
import { inc } from "../App/Utilities/mathUtils";
import { cons, List } from "./List";
import { fst, Pair, snd } from "./Pair";
import { show } from "./Show";
import { fst, Pair, snd } from "./Tuple";
/**
* `range :: Int a => (a, a) -> [a]`
+1 -1
View File
@@ -10,7 +10,7 @@ import { pipe } from "../App/Utilities/pipe";
import { Identity, runIdentity } from "../Control/Monad/Identity";
import { fmap } from "./Functor";
import { Const, getConst } from "./Functor/Const";
import { fst, Pair, snd } from "./Pair";
import { fst, Pair, snd } from "./Tuple";
interface Getter <S, T, A, B> {
(lift: (x: A) => Const<A, B>): (m: S) => Const<A, T>
+58 -69
View File
@@ -12,87 +12,69 @@ import { not } from "./Bool";
import { equals } from "./Eq";
import { ident, thrush } from "./Function";
import { fmap, fmapF } from "./Functor";
import { Internals } from "./Internals";
import { fromJust, imapMaybe, isJust, Just, mapMaybe, Maybe, maybe, Nothing } from "./Maybe";
import { isLTorEQ, Ordering } from "./Ord";
import { first, fst, Pair, second, snd } from "./Pair";
import { fromMap, lookupF, OrderedMap } from "./OrderedMap";
import { fromDefault, RecordBase } from "./Record";
import { show } from "./Show";
import { first, fst, Pair, second, snd } from "./Tuple";
export import NonEmptyList = Internals.NonEmptyList
export import Cons = Internals.Cons
import Nil = Internals.Nil
import isNil = Internals.isNil
import Maybe = Internals.Maybe
import Just = Internals.Just
import Nothing = Internals.Nothing
import isJust = Internals.isJust
import OrderedMap = Internals.OrderedMap
import _OrderedMap = Internals._OrderedMap
import Some = Internals.Some
import Nullable = Internals.Nullable
const fromJust =
<A extends Some> (x: Just<A>): A => {
if (isJust (x)) {
return x.value
}
// PROTOTYPE
throw new TypeError (`Cannot extract a value out of type Nothing.`)
}
interface ListPrototype<A> {
readonly isList: true
[Symbol.iterator] (): IterableIterator<A>
}
const imapMaybe =
<A extends Some, B extends Some>
(f: (index: number) => (x: A) => Maybe<B>) =>
ifoldr<A, List<B>>
(index => x => acc =>
pipe (
f (index),
maybe<List<B>> (acc)
(cons (acc)))
(x))
(List.empty)
const ListPrototype =
Object.freeze<ListPrototype<any>> ({
isList: true,
*[Symbol.iterator] () {
// tslint:disable-next-line: no-this-assignment
let current = this as List<any>
const mapMaybe =
<A extends Some, B extends Some>
(f: (x: A) => Maybe<B>) =>
List.foldr<A, List<B>> (pipe (
f,
maybe<(xs: List<B>) => List<B>> (ident)
(consF)
))
(List.empty)
while (!isNil (current)) {
yield current .x
current = current .xs
}
},
})
const maybe =
<B extends Some> (def: B) =>
<A extends Some> (f: (x: A) => B) =>
(x: Maybe<A>) =>
isJust (x) ? f (x .value) : def
const fromMap =
<K, A> (xs: ReadonlyMap<K, A>): OrderedMap<K, A> => {
if (xs instanceof Map) {
return _OrderedMap (xs)
}
throw new TypeError (
`fromArray requires a native Map but instead it received ${show (xs)}`
)
}
const Maybe =
<A extends Some> (x: A | Nullable): Maybe<A> =>
x !== null && x !== undefined ? Just (x) : Nothing
const lookupF =
<K, A>
(m: OrderedMap<K, A>) =>
(key: K): Maybe<A> =>
Maybe (m .value .get (key))
// CONSTRUCTOR
// CONSTRUCTORS
export type List<A> = Nil | Cons<A>
export type NonEmptyList<A> = Cons<A>
export interface Nil extends ListPrototype<never> { }
const Nil: Nil = Object.create (ListPrototype)
const isNil = (xs: List<any>): xs is Nil => xs === Nil
export interface Cons<A> extends ListPrototype<A> {
readonly x: A
readonly xs: List<A>
}
export const Cons =
<A> (x: A, xs: List<A>): Cons<A> =>
Object.create (
ListPrototype,
{
x: {
value: x,
enumerable: true,
},
xs: {
value: xs,
enumerable: true,
},
}
)
/**
* `List :: (...a) -> [a]`
*
@@ -1908,6 +1890,14 @@ export const replaceStr =
// OWN METHODS
/**
* Checks if the given value is a `List`.
* @param x The value to test.
*/
export const isList =
<A, A1> (x: A | List<A1>): x is List<A1> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === ListPrototype
/**
* `unsafeIndex :: [a] -> Int -> a`
*
@@ -2078,7 +2068,6 @@ export const mapByIdKeyMap =
List.mapByIdKeyMap = mapByIdKeyMap
export import isList = Internals.isList
/**
* Returns `True` if the passed value is a non-empty string, `False` if the
+1 -3
View File
@@ -1,6 +1,4 @@
import { Internals } from "./Internals";
import Either = Internals.Either
import { Either } from "./Either";
// PROTOTYPE
+155 -78
View File
@@ -19,17 +19,42 @@ import * as Math from "../App/Utilities/mathUtils";
import { pipe } from "../App/Utilities/pipe";
import { cnst, flip, ident } from "./Function";
import { fmap, fmapF } from "./Functor";
import { Internals } from "./Internals";
import { cons, consF, head, ifoldr, List } from "./List";
export import Just = Internals.Just
export import Nothing = Internals.Nothing
export import isJust = Internals.isJust
export import isNothing = Internals.isNothing
// PROTOTYPES
interface JustPrototype {
readonly isJust: true
readonly isNothing: false
}
const JustPrototype =
Object.freeze<JustPrototype> ({
isJust: true,
isNothing: false,
})
interface NothingPrototype extends Object {
readonly isJust: false
readonly isNothing: true
}
const NothingPrototype: NothingPrototype =
Object.freeze<NothingPrototype> ({
isJust: false,
isNothing: true,
})
// CONSTRUCTORS
export interface Just<A extends Some> extends JustPrototype {
readonly value: A
}
export interface Nothing extends NothingPrototype { }
export type Maybe<A extends Some> = Just<A> | Nothing
/**
@@ -41,8 +66,66 @@ export const Maybe =
<A extends Some> (x: A | Nullable): Maybe<A> =>
x !== null && x !== undefined ? Just (x) : Nothing
/**
* `Just :: a -> Maybe a`
*
* Creates a new `Just` from the passed value.
*/
export const Just = <A extends Some> (x: A): Just<A> => {
if (x !== null && x !== undefined) {
return Object.create (
JustPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
}
// MAYBE FUNCTIONS (PART 1)
throw new TypeError ("Cannot create a Just from a nullable value.")
}
/**
* `Nothing :: Maybe a`
*
* The empty `Maybe`.
*/
export const Nothing: Nothing = Object.create (NothingPrototype)
// MAYBE FUNCTIONS
/**
* `maybe :: b -> (a -> b) -> Maybe a -> b`
*
* The `maybe` function takes a default value, a function, and a `Maybe`
* value. If the `Maybe` value is `Nothing`, the function returns the default
* value. Otherwise, it applies the function to the value inside the `Just`
* and returns the result.
*/
export const maybe =
<B extends Some> (def: B) =>
<A extends Some> (f: (x: A) => B) =>
foldl<A, B> (() => f) (def)
/**
* `isJust :: Maybe a -> Bool`
*
* The `isJust` function returns `true` if its argument is of the form
* `Just _`.
*/
export const isJust =
<A extends Some> (x: Maybe<A>): x is Just<A> =>
Object.getPrototypeOf (x) === JustPrototype
/**
* `isNothing :: Maybe a -> Bool`
*
* The `isNothing` function returns `true` if its argument is `Nothing`.
*/
export const isNothing = (x: Maybe<Some>): x is Nothing => x === Nothing
/**
* `fromJust :: Maybe a -> a`
@@ -85,6 +168,58 @@ export const fromMaybe_ =
<A extends Some> (def: () => A) => (x: Maybe<A>): A =>
isJust (x) ? x .value : def ()
/**
* `listToMaybe :: [a] -> Maybe a`
*
* The `listToMaybe` function returns `Nothing` on an empty list or `Just a`
* where `a` is the first element of the list.
*/
export const listToMaybe =
<A extends Some> (xs: List<A>): Maybe<A> =>
List.fnull (xs) ? Nothing : Just (head (xs))
/**
* `maybeToList :: Maybe a -> [a]`
*
* The `maybeToList` function returns an empty list when given `Nothing` or a
* singleton list when not given `Nothing`.
*/
export const maybeToList =
<A extends Some>(x: Maybe<A>): List<A> =>
isJust (x) ? List.pure (x .value) : List.empty
/**
* `catMaybes :: [Maybe a] -> [a]`
*
* The `catMaybes` function takes a list of `Maybe`s and returns a list of all
* the `Just` values.
*/
export const catMaybes =
<A extends Some>
(xs: List<Maybe<A>>): List<A> =>
List.foldr<Maybe<A>, List<A>> (maybe<(xs: List<A>) => List<A>> (ident)
(consF))
(List.empty)
(xs)
/**
* `mapMaybe :: (a -> Maybe b) -> [a] -> [b]`
*
* The `mapMaybe` function is a version of `map` which can throw out elements.
* If particular, the functional argument returns something of type `Maybe b`.
* If this is `Nothing`, no element is added on to the result list. If it is
* `Just b`, then `b` is included in the result list.
*/
export const mapMaybe =
<A extends Some, B extends Some>
(f: (x: A) => Maybe<B>) =>
List.foldr<A, List<B>> (pipe (
f,
maybe<(xs: List<B>) => List<B>> (ident)
(consF)
))
(List.empty)
// APPLICATIVE
@@ -389,9 +524,7 @@ export const foldl =
*
* List of elements of a structure, from left to right.
*/
export const toList =
<A extends Some>(x: Maybe<A>): List<A> =>
isJust (x) ? List.pure (x .value) : List.empty
export const toList = maybeToList
/**
* `null :: Maybe a -> Bool`
@@ -656,75 +789,20 @@ export const mappend =
: x
// MAYBE FUNCTIONS (PART 2)
/**
* `maybe :: b -> (a -> b) -> Maybe a -> b`
*
* The `maybe` function takes a default value, a function, and a `Maybe`
* value. If the `Maybe` value is `Nothing`, the function returns the default
* value. Otherwise, it applies the function to the value inside the `Just`
* and returns the result.
*/
export const maybe =
<B extends Some> (def: B) =>
<A extends Some> (f: (x: A) => B) =>
foldl<A, B> (() => f) (def)
/**
* `listToMaybe :: [a] -> Maybe a`
*
* The `listToMaybe` function returns `Nothing` on an empty list or `Just a`
* where `a` is the first element of the list.
*/
export const listToMaybe =
<A extends Some> (xs: List<A>): Maybe<A> =>
List.fnull (xs) ? Nothing : Just (head (xs))
/**
* `maybeToList :: Maybe a -> [a]`
*
* The `maybeToList` function returns an empty list when given `Nothing` or a
* singleton list when not given `Nothing`.
*/
export const maybeToList = toList
/**
* `catMaybes :: [Maybe a] -> [a]`
*
* The `catMaybes` function takes a list of `Maybe`s and returns a list of all
* the `Just` values.
*/
export const catMaybes =
<A extends Some>
(xs: List<Maybe<A>>): List<A> =>
List.foldr<Maybe<A>, List<A>> (maybe<(xs: List<A>) => List<A>> (ident)
(consF))
(List.empty)
(xs)
/**
* `mapMaybe :: (a -> Maybe b) -> [a] -> [b]`
*
* The `mapMaybe` function is a version of `map` which can throw out elements.
* If particular, the functional argument returns something of type `Maybe b`.
* If this is `Nothing`, no element is added on to the result list. If it is
* `Just b`, then `b` is included in the result list.
*/
export const mapMaybe =
<A extends Some, B extends Some>
(f: (x: A) => Maybe<B>) =>
List.foldr<A, List<B>> (pipe (
f,
maybe<(xs: List<B>) => List<B>> (ident)
(consF)
))
(List.empty)
// CUSTOM MAYBE FUNCTIONS
export import isMaybe = Internals.isMaybe
/**
* `isMaybe :: a -> Bool`
*
* The `isMaybe` function returns `True` if its argument is a `Maybe`.
*/
export const isMaybe =
<A, A0 extends Some>(x: A | Maybe<A0>): x is Maybe<A0> =>
typeof x === "object"
&& x !== null
&& (x === Nothing || Object.getPrototypeOf (x) === JustPrototype)
Maybe.isMaybe = isMaybe
/**
* `normalize :: (a | Maybe a) -> Maybe a`
@@ -963,7 +1041,6 @@ Maybe.maybeToList = maybeToList
Maybe.catMaybes = catMaybes
Maybe.mapMaybe = mapMaybe
Maybe.isMaybe = isMaybe
Maybe.normalize = normalize
Maybe.ensure = ensure
Maybe.imapMaybe = imapMaybe
@@ -976,7 +1053,7 @@ Maybe.maybeRNullF = maybeRNullF
// TYPE HELPERS
export type MaybeI<A> = A extends Internals.Maybe<infer AI> ? AI : never
export type MaybeI<A> = A extends Maybe<infer AI> ? AI : never
// tslint:disable-next-line:interface-over-type-literal
export type Some = {}
+48 -11
View File
@@ -10,31 +10,53 @@
import { add, multiply } from "../App/Utilities/mathUtils";
import { pipe } from "../App/Utilities/pipe";
import { not } from "./Bool";
import { Either, fromRight_, isLeft, Right } from "./Either";
import { Either, isLeft, Right } from "./Either";
import { fromRight_ } from "./Either/Extra";
import { equals } from "./Eq";
import { ident } from "./Function";
import { fmapF } from "./Functor";
import { Internals } from "./Internals";
import { append, List } from "./List";
import { bind, fromMaybe, Just, Maybe, maybe, maybe_ } from "./Maybe";
import { OrderedSet } from "./OrderedSet";
import { StringKeyObject } from "./Record";
import { show } from "./Show";
import { Pair, Tuple } from "./Tuple";
import _OrderedMap = Internals._OrderedMap
import OrderedSet = Internals.OrderedSet
import mapFromArray = Internals.mapFromArray
interface StringKeyObject<V> {
readonly [id: string]: V
// PROTOTYPE
export interface OrderedMapPrototype<K, A> {
[Symbol.iterator] (): IterableIterator<[K, A]>
readonly isOrderedMap: true
}
const OrderedMapPrototype =
Object.freeze<OrderedMapPrototype<any, any>> ({
[Symbol.iterator] (this: OrderedMap<any, any>) {
return this .value [Symbol.iterator] ()
},
isOrderedMap: true,
})
// CONSTRUCTOR
export interface OrderedMap<K, A> extends Internals.OrderedMapPrototype<K, A> {
export interface OrderedMap<K, A> extends OrderedMapPrototype<K, A> {
readonly value: ReadonlyMap<K, A>
}
const _OrderedMap =
<K, A> (x: ReadonlyMap<K, A>): OrderedMap<K, A> =>
Object.create (
OrderedMapPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
/**
* `fromUniquePairs :: ...(k, a) -> Map k a`
*
@@ -823,7 +845,7 @@ export const assocs = <K, A> (mp: OrderedMap<K, A>): List<Pair<K, A>> =>
* The set of all keys of the map.
*/
export const keysSet = <K> (mp: OrderedMap<K, any>): OrderedSet<K> =>
Internals._OrderedSet (new Set (mp .value .keys ()))
OrderedSet.fromSet (new Set (mp .value .keys ()))
/**
* `fromSet :: (k -> a) -> Set k -> Map k a`
@@ -1041,14 +1063,29 @@ export const lookup2F =
(x => fmapF (lookup (key) (m2))
(f (x)))
export import isOrderedMap = Internals.isOrderedMap
/**
* Checks if the given value is a `OrderedMap`.
* @param x The value to test.
*/
export const isOrderedMap =
(x: any): x is OrderedMap<any, any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === OrderedMapPrototype
/**
* `fromArray :: Array (k, a) -> Map k a`
*
* Creates a new `Set` instance from the passed native `Array`.
*/
export const fromArray = mapFromArray (show)
export const fromArray =
<K, A> (xs: ReadonlyArray<[K, A]>): OrderedMap<K, A> => {
if (Array.isArray (xs)) {
return _OrderedMap (new Map (xs))
}
throw new TypeError (
`fromArray requires an array but instead it received ${show (xs)}`
)
}
/**
* `mapMEitherWithKey :: (k -> a -> Either e b) -> OrderedMap k a -> Either e (OrderedMap k b)`
+46 -8
View File
@@ -11,22 +11,45 @@ import { pipe } from "../App/Utilities/pipe";
import { not } from "./Bool";
import { equals, notEquals } from "./Eq";
import { ident } from "./Function";
import { Internals } from "./Internals";
import { append, List } from "./List";
import { append, isList, List } from "./List";
import { Maybe } from "./Maybe";
import { show } from "./Show";
import isList = Internals.isList
import _OrderedSet = Internals._OrderedSet
import setFromArray = Internals.setFromArray
// PROTOTYPE
export interface OrderedSetPrototype<A> {
[Symbol.iterator] (): IterableIterator<A>
readonly isOrderedSet: true
}
const OrderedSetPrototype =
Object.freeze<OrderedSetPrototype<any>> ({
[Symbol.iterator] (this: OrderedSet<any>) {
return this .value [Symbol.iterator] ()
},
isOrderedSet: true,
})
// CONSTRUCTOR
export interface OrderedSet<A> extends Internals.OrderedSetPrototype<A> {
export interface OrderedSet<A> extends OrderedSetPrototype<A> {
readonly value: ReadonlySet<A>
}
const _OrderedSet =
<A> (x: ReadonlySet<A>): OrderedSet<A> =>
Object.create (
OrderedSetPrototype,
{
value: {
value: x,
enumerable: true,
},
}
)
/**
* `fromUniqueElements :: ...a -> Set a`
*
@@ -518,14 +541,29 @@ export const toggle =
<A> (x: A) => (xs: OrderedSet<A>): OrderedSet<A> =>
member (x) (xs) ? sdelete (x) (xs) : insert (x) (xs)
export import isOrderedSet = Internals.isOrderedSet
/**
* Checks if the given value is a `OrderedSet`.
* @param x The value to test.
*/
export const isOrderedSet =
(x: any): x is OrderedSet<any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === OrderedSetPrototype
/**
* `fromArray :: Array a -> Set a`
*
* Creates a new `Set` instance from the passed native `Array`.
*/
export const fromArray = setFromArray (show)
export const fromArray =
<A> (xs: ReadonlyArray<A>): OrderedSet<A> => {
if (Array.isArray (xs)) {
return _OrderedSet (new Set (xs))
}
throw new TypeError (
`fromArray requires an array but instead it received ${show (xs)}`
)
}
// NAMESPACED FUNCTIONS
-187
View File
@@ -1,187 +0,0 @@
/**
* @module Data.Pair
*
* A pair (`(a, b)`) is a simple flat data structure for lists of values of
* different types but constant length.
*
* @author Lukas Obermann
*/
import { Internals } from "./Internals";
import { Tuple } from "./Tuple";
import * as Curry from "./Tuple/Curry";
// CONSTRUCTOR
export { Pair } from "./Tuple";
// BIFUNCTOR
/**
* `bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)`
*
* @deprecated use Tuple.bimap
*/
export const bimap = Tuple.bimap
/**
* `first :: (a -> b) -> (a, c) -> (b, c)`
*
* @deprecated use Tuple.first
*/
export const first = Tuple.first
/**
* `second :: (b -> c) -> (a, b) -> (a, c)`
*
* @deprecated use Tuple.second
*/
export const second = Tuple.second
// PAIR FUNCTIONS
/**
* `fst :: (a, b) -> a`
*
* Extract the first component of a pair.
*
* @deprecated use Tuple.fst
*/
export const fst = Tuple.fst
/**
* `snd :: (a, b) -> b`
*
* Extract the second component of a pair.
*
* @deprecated use Tuple.snd
*/
export const snd = Tuple.snd
/**
* `curry :: ((a, b) -> c) -> a -> b -> c`
*
* `curry` converts an uncurried function to a curried function.
*
* @deprecated use Tuple.curry
*/
export const curry = Tuple.curry
/**
* `curryN :: ((a, b) -> c) -> a -> b -> c`
*
* `curryN` converts an uncurried function to a curried function.
*
* @deprecated use Tuple.Curry.curryN
*/
export const curryN = Curry.curryN
/**
* `uncurry :: (a -> b -> c) -> (a, b) -> c`
*
* `uncurry` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.uncurry
*/
export const uncurry = Tuple.uncurry
/**
* `uncurryN :: (a -> b -> c) -> (a, b) -> c`
*
* `uncurryN` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN
*/
export const uncurryN = Curry.uncurryN
/**
* `uncurryN3 :: (a -> b -> c -> d) -> (a, b, c) -> d`
*
* `uncurryN3` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN3
*/
export const uncurryN3 = Curry.uncurryN3
/**
* `uncurryN4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e`
*
* `uncurryN4` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN4
*/
export const uncurryN4 = Curry.uncurryN4
/**
* `uncurryN5 :: (a -> b -> c -> d -> e -> f) -> (a, b, c, d, e) -> f`
*
* `uncurryN5` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN5
*/
export const uncurryN5 = Curry.uncurryN5
/**
* `uncurryN6 :: (a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g`
*
* `uncurryN6` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN6
*/
export const uncurryN6 = Curry.uncurryN6
/**
* `uncurryN7 :: (a -> b -> c -> d -> e -> f -> g -> h) -> (a, b, c, d, e, f, g) -> h`
*
* `uncurryN7` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN7
*/
export const uncurryN7 = Curry.uncurryN7
/**
* `uncurryN8 :: (a -> b -> c -> d -> e -> f -> g -> h -> i) -> (a, b, c, d, e, f, g, h) -> i`
*
* `uncurryN8` converts a curried function to a function on pairs.
*
* @deprecated use Tuple.Curry.uncurryN8
*/
export const uncurryN8 = Curry.uncurryN8
/**
* `swap :: (a, b) -> (b, a)`
*
* Swap the components of a pair.
*
* @deprecated use Tuple.swap
*/
export const swap = Tuple.swap
// CUSTOM FUNCTIONS
/**
* `toArray :: (a, b) -> Array (b | a)`
*
* Converts the pair to a native `Array`.
*
* @deprecated use Tuple.toArray
*/
export const toArray = Tuple.toArray
/**
* `fromArray :: (a, b) -> Array (b | a)`
*
* Creates a pair from a native `Array` of length `2`.
*
* @deprecated use Tuple.fromArray
*/
export const fromArray = Tuple.fromArray
/**
* @deprecated use Tuple.isTuple
*/
export import isPair = Internals.isTuple
+26 -23
View File
@@ -9,25 +9,22 @@
import { pipe } from "../App/Utilities/pipe";
import { not } from "./Bool";
import { equals } from "./Eq";
import { Internals } from "./Internals";
import { lens, Lens_ } from "./Lens";
import { isJust, isMaybe, isNothing, Maybe, Nothing } from "./Maybe";
import { elem, foldl, fromArray, OrderedSet } from "./OrderedSet";
import { show } from "./Show";
import RecordPrototype = Internals.RecordPrototype
import OrderedSet = Internals.OrderedSet
import Maybe = Internals.Maybe
const elem =
<A> (e: A) => (xs: OrderedSet<A>): boolean =>
[...xs .value] .some (equals (e))
// PROTOTYPE
const foldl =
<A, B>
(f: (acc: B) => (current: A) => B) =>
(initial: B) =>
(xs: OrderedSet<A>): B =>
[...xs .value] .reduce<B> ((acc, e) => f (acc) (e), initial)
export interface RecordPrototype {
readonly isRecord: true
}
export const RecordPrototype =
Object.freeze<RecordPrototype> ({
isRecord: true,
})
// CONSTRUCTOR
@@ -104,7 +101,7 @@ export const fromDefault =
{} as Required<A>
))
const keys = Internals.setFromArray (show) (Object.keys (def))
const keys = fromArray (Object.keys (def))
const unique = Symbol ("Record")
@@ -119,19 +116,19 @@ export const fromDefault =
// Maybe undefined!
const value =
(x as Required<A>) [key] as MaybeOrPartialMaybe<A[string]> === undefined
? Internals.Nothing
? Nothing
: (x as Required<A>) [key] as MaybeOrPartialMaybe<A[string]>
const defaultValue = defaultValues [key]
return elem (key) (keys)
&& (
Internals.isMaybe (defaultValue) && Internals.isJust (value)
isMaybe (defaultValue) && isJust (value)
|| (
!Internals.isMaybe (defaultValue)
!isMaybe (defaultValue)
&& value !== null
&& value !== undefined
&& !Internals.isNothing (value)
&& isJust (value)
)
)
? { ...acc, [key]: value } as PartialMaybeOrNothing<A>
@@ -256,7 +253,7 @@ const accessor = <A extends RecordBase> (key: keyof A) => (r: Record<A>) => {
if (elem<keyof A> (key) (r .keys)) {
const x = r .values [key]
return Internals.isMaybe (x) && Internals.isNothing (x) ? r .defaultValues [key] : x
return isMaybe (x) && isNothing (x) ? r .defaultValues [key] : x
}
throw new TypeError (`Key ${show (key)} is not in Record ${show (r)}!`)
@@ -306,7 +303,13 @@ export const notMember = (key: string) => pipe (member (key), not)
export const toObject = <A extends RecordBase> (r: Record<A>): A =>
({ ...r .defaultValues, ...r .values })
export import isRecord = Internals.isRecord
/**
* Checks if the given value is a `Record`.
* @param x The value to test.
*/
export const isRecord =
(x: any): x is Record<any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === RecordPrototype
// NAMESPACED FUNCTIONS
@@ -384,13 +387,13 @@ type PartialMaybePartialKeys<A> = {
[K in keyof A]: A[K] extends Maybe<any> ? K : never
} [keyof A]
type MaybeOrPartialMaybe<A> = A extends Maybe<any> ? A : A | Internals.Nothing
type MaybeOrPartialMaybe<A> = A extends Maybe<any> ? A : A | Nothing
/**
* All `Maybe` properties will be optional and all others required.
*/
export type PartialMaybeOrNothing<A> = {
[K in PartialMaybeRequiredKeys<A>]-?: A[K] extends Maybe<any> ? never : (A[K] | Internals.Nothing)
[K in PartialMaybeRequiredKeys<A>]-?: A[K] extends Maybe<any> ? never : (A[K] | Nothing)
} & {
[K in PartialMaybePartialKeys<A>]?: A[K] extends Maybe<any> ? A[K] : never
}
+34 -27
View File
@@ -7,20 +7,27 @@
*/
import { pipe } from "../App/Utilities/pipe";
import { Internals } from "./Internals";
import { isIO } from "../System/IO";
import { isEither, isRight } from "./Either";
import { consF, fnull, isList, List } from "./List";
import { isJust, isMaybe } from "./Maybe";
import { GT, isOrdering, LT } from "./Ord";
import { isOrderedMap } from "./OrderedMap";
import { isOrderedSet } from "./OrderedSet";
import { isRecord } from "./Record";
import { isTuple } from "./Tuple";
const intercalate =
(separator: string) => (xs: Internals.List<number | string>): string =>
Internals.isNil (xs)
(separator: string) => (xs: List<number | string>): string =>
fnull (xs)
? ""
: Internals.isNil (xs .xs)
: fnull (xs .xs)
? xs .x .toString ()
: xs .x .toString () + separator + intercalate (separator) (xs .xs)
const map =
<A, B> (f: (x: A) => B) => (xs: Internals.List<A>): Internals.List<B> =>
Internals.isNil (xs) ? Internals.Nil : Internals.Cons (f (xs .x), map (f) (xs .xs))
<A, B> (f: (x: A) => B) => (xs: List<A>): List<B> =>
fnull (xs) ? List () : consF (f (xs .x)) (map (f) (xs .xs))
const trimStart = (str: string) => str .replace (/^\s+/, "")
@@ -31,27 +38,27 @@ const trimStart = (str: string) => str .replace (/^\s+/, "")
*/
// tslint:disable-next-line: cyclomatic-complexity
export const show = (x: any): string => {
if (Internals.isMaybe (x)) {
if (Internals.isJust (x)) {
if (isMaybe (x)) {
if (isJust (x)) {
return `Just (${show (x.value)})`
}
return `Nothing`
}
if (Internals.isEither (x)) {
if (Internals.isRight (x)) {
if (isEither (x)) {
if (isRight (x)) {
return `Right (${show (x .value)})`
}
return `Left (${show (x .value)})`
}
if (Internals.isList (x)) {
if (isList (x)) {
return `[${intercalate (", ") (map (show) (x))}]`
}
if (Internals.isTuple (x)) {
if (isTuple (x)) {
const arr: any = []
for (let i = 0; i < x .length; i++) {
@@ -62,17 +69,17 @@ export const show = (x: any): string => {
return `(${arr .map (show) .join (", ")})`
}
if (Internals.isOrderedSet (x)) {
if (isOrderedSet (x)) {
return `Set (${[...x] .map (show) .join (", ")})`
}
if (Internals.isOrderedMap (x)) {
if (isOrderedMap (x)) {
return `Map (${
[...x] .map (([k, v]) => `${show (k)} = ${show (v)}`) .join (", ")
})`
}
if (Internals.isRecord (x)) {
if (isRecord (x)) {
return `{ ${
[...x .keys .value]
.sort ()
@@ -88,7 +95,7 @@ export const show = (x: any): string => {
} }`
}
if (Internals.isIO (x)) {
if (isIO (x)) {
return `IO`
}
@@ -141,8 +148,8 @@ export const show = (x: any): string => {
const showPDepth = (depth: number) => (x: any): string => {
const dws = " " .repeat (depth * 2) // depth whitespace
if (Internals.isMaybe (x)) {
if (Internals.isJust (x)) {
if (isMaybe (x)) {
if (isJust (x)) {
const str = trimNextDepth (depth) (x.value)
if (/\n/ .test (str)) {
@@ -155,10 +162,10 @@ const showPDepth = (depth: number) => (x: any): string => {
return `${dws}Nothing`
}
if (Internals.isEither (x)) {
if (isEither (x)) {
const str = trimNextDepth (depth) (x.value)
if (Internals.isRight (x)) {
if (isRight (x)) {
if (/\n/ .test (str)) {
return `${dws}Right (\n${dws} ${str}${dws}\n)`
}
@@ -173,15 +180,15 @@ const showPDepth = (depth: number) => (x: any): string => {
return `${dws}Left ${wrapParens (str)}`
}
if (Internals.isList (x)) {
if (Internals.isNil (x)) {
if (isList (x)) {
if (fnull (x)) {
return `${dws}[]`
}
return `${dws}[ ${[...x] .map (trimNextDepth (depth)) .join (`\n${dws}, `)} ]`
}
if (Internals.isTuple (x)) {
if (isTuple (x)) {
const arr: any = []
for (let i = 0; i < x .length; i++) {
@@ -192,17 +199,17 @@ const showPDepth = (depth: number) => (x: any): string => {
return `${dws}( ${arr .map (trimNextDepth (depth)) .join (`\n${dws}, `)}\n${dws})`
}
if (Internals.isOrderedSet (x)) {
if (isOrderedSet (x)) {
return `${dws}Set (${[...x] .map (trimNextDepth (depth + 2)) .join (`\n${dws} , `)})`
}
if (Internals.isOrderedMap (x)) {
if (isOrderedMap (x)) {
return `${dws}Map (${
[...x] .map (([k, v]) => `${show (k)} = ${show (v)}`) .join (`\n${dws} , `)
})`
}
if (Internals.isRecord (x)) {
if (isRecord (x)) {
return `${dws}{ ${
[...x .keys .value]
.sort ()
@@ -219,7 +226,7 @@ const showPDepth = (depth: number) => (x: any): string => {
} }`
}
if (Internals.isIO (x)) {
if (isIO (x)) {
return `${dws}IO`
}
+2 -1
View File
@@ -1,5 +1,6 @@
import { pipe } from "../../App/Utilities/pipe";
import { Either, eitherToMaybe, Left, Right } from "../Either";
import { Either, Left, Right } from "../Either";
import { eitherToMaybe } from "../Either/Extra";
export const tryParseJSON =
(x: string): Either<Error, any> => {
+41 -6
View File
@@ -7,16 +7,26 @@
* @author Lukas Obermann
*/
import { Internals } from "./Internals";
// PROTOTYPE
export interface TuplePrototype {
readonly isTuple: true
}
const TuplePrototype =
Object.freeze<TuplePrototype> ({
isTuple: true,
})
// CONSTRUCTOR
export interface Tuple<A extends any[]> extends Internals.TuplePrototype {
export interface Tuple<A extends any[]> extends TuplePrototype {
readonly phantom: A
readonly values: { [index: number]: any }
readonly length: number
readonly prototype: Internals.TuplePrototype
readonly prototype: TuplePrototype
}
interface TupleConstructor {
@@ -45,8 +55,26 @@ interface TupleConstructor {
}
export const Tuple =
((...args: any[]) => {
return Internals._Tuple (...args)
(<A extends any[]> (...values: A): Tuple<A> => {
const obj: { [index: number]: any } = {}
values.forEach ((e, i) => {
obj [i] = e
})
return Object.create (
TuplePrototype,
{
values: {
value: Object.freeze (obj),
enumerable: true,
},
length: {
value: values .length,
enumerable: true,
},
}
)
}) as TupleConstructor
@@ -214,7 +242,14 @@ export const toArray =
*/
export const fromArray = <A extends any[]> (x: A): Tuple<A> => Tuple (...x)
export import isTuple = Internals.isTuple
/**
* `isTuple :: a -> Bool`
*
* The `isTuple` function returns `True` if its argument is a `Tuple`.
*/
export const isTuple =
<A, A0 extends any[]>(x: A | Tuple<A0>): x is Tuple<A0> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === TuplePrototype
// NAMESPACED FUNCTIONS
+2 -2
View File
@@ -1,5 +1,5 @@
import { Internals } from "../Data/Internals";
import { showP } from "../Data/Show";
import { IO } from "../System/IO";
/**
* `trace :: Show a => String -> a -> a`
@@ -20,7 +20,7 @@ export const trace = (msg: string) => <A> (x: A) => (console.log (msg), x)
export const traceShowIO =
(msg: string) =>
<A> (x: A) =>
Internals.IO (async () => (console.log (`${msg} ${showP (x)}`), Promise.resolve (x)))
IO (async () => (console.log (`${msg} ${showP (x)}`), Promise.resolve (x)))
/**
* `traceShow :: Show a => String -> a -> a`
+47 -15
View File
@@ -15,19 +15,30 @@ import * as util from "util";
import { pipe } from "../App/Utilities/pipe";
import { ident } from "../Data/Function";
import { fmapF } from "../Data/Functor";
import { Internals } from "../Data/Internals";
import { showP } from "../Data/Show";
// PROTOTYPE
export interface IOPrototype {
readonly isIO: true
}
export const IOPrototype =
Object.freeze<IOPrototype> ({
isIO: true,
})
// CONSTRUCTOR
export interface IO<A> extends Internals.IOPrototype {
export interface IO<A> extends IOPrototype {
readonly f: () => Promise<A>
}
interface IOConstructor {
<A> (f: () => Promise<A>): IO<A>
pure: <A> (x: A) => Internals.IO<A>
pure: <A> (x: A) => IO<A>
bind: <A> (x: IO<A>) => <B> (f: (x: A) => IO<B>) => IO<B>
bindF: <A, B> (f: (x: A) => IO<B>) => (x: IO<A>) => IO<B>
then: (x: IO<any>) => <A> (y: IO<A>) => IO<A>
@@ -52,7 +63,21 @@ interface IOConstructor {
runIO: <A>(x: IO<A>) => IO<void>
}
export const IO: IOConstructor = Internals.IO as IOConstructor
export const IO =
(<A> (f: () => Promise<A>): IO<A> => {
if (typeof f === "function") {
return Object.create (
IOPrototype,
{
f: {
value: f,
},
}
)
}
throw new TypeError ("Cannot create an IO action from a value that is not a function.")
}) as IOConstructor
// APPLICATIVE
@@ -62,7 +87,7 @@ export const IO: IOConstructor = Internals.IO as IOConstructor
*
* Lift a value.
*/
export const pure = <A> (x: A) => Internals.IO (() => Promise.resolve (x))
export const pure = <A> (x: A) => IO (() => Promise.resolve (x))
IO.pure = pure
@@ -79,7 +104,7 @@ export const bind =
(f: (x: A) => IO<B>): IO<B> => {
const res = x .f ()
return Internals.IO (() => res .then (pipe (f, y => y.f ()))
return IO (() => res .then (pipe (f, y => y.f ()))
.catch (err => { throw err }))
}
@@ -182,7 +207,7 @@ const readFileP = util.promisify (fs.readFile)
*/
export const readFile =
(path: FilePath) =>
Internals.IO (async () => readFileP (path, "utf8"))
IO (async () => readFileP (path, "utf8"))
IO.readFile = readFile
@@ -197,7 +222,7 @@ const writeFileP = util.promisify (fs.writeFile)
export const writeFile =
(path: FilePath) =>
(data: string | Buffer) =>
Internals.IO (async () => writeFileP (path, data, "utf8"))
IO (async () => writeFileP (path, data, "utf8"))
IO.writeFile = writeFile
@@ -210,7 +235,7 @@ const deleteFileP = util.promisify (fs.unlink)
*/
export const deleteFile =
(path: FilePath) =>
Internals.IO (async () => deleteFileP (path))
IO (async () => deleteFileP (path))
IO.deleteFile = deleteFile
@@ -223,7 +248,7 @@ const existsFileP = util.promisify (fs.access)
*/
export const existsFile =
(path: FilePath) =>
Internals.IO (async () => existsFileP (path, fs.constants.F_OK)
IO (async () => existsFileP (path, fs.constants.F_OK)
.then (() => true)
.catch (() => false))
@@ -240,7 +265,7 @@ const copyFileP = util.promisify (fs.copyFile)
export const copyFile =
(origin: FilePath) =>
(dest: FilePath) =>
Internals.IO (async () => copyFileP (origin, dest))
IO (async () => copyFileP (origin, dest))
IO.copyFile = copyFile
@@ -257,14 +282,21 @@ IO.copyFile = copyFile
*/
export const print =
(x: any) =>
Internals.IO (async () => Promise.resolve (console.log (showP (x))))
IO (async () => Promise.resolve (console.log (showP (x))))
IO.print = print
// CUSTOM FUNCTIONS
export import isIO = Internals.isIO
/**
* `isIO :: a -> Bool`
*
* The `isIO` function returns `True` if its argument is an `IO`.
*/
export const isIO =
(x: any): x is IO<any> =>
typeof x === "object" && x !== null && Object.getPrototypeOf (x) === IOPrototype
IO.isIO = isIO
@@ -287,7 +319,7 @@ export const toIO =
<A extends any[], B>
(f: (...args: A) => Promise<B>) =>
(...args: A): IO<B> =>
Internals.IO (() => f (...args))
IO (() => f (...args))
IO.toIO = toIO
@@ -300,7 +332,7 @@ export const runIO =
<A> (x: IO<A>): IO<void> => {
x .f () .catch (err => { throw err })
return Internals.IO (async () => { return })
return IO (async () => { return })
}
IO.runIO = runIO
+1 -1
View File
@@ -24,7 +24,7 @@ import { flip } from "./Data/Function";
import { fmap } from "./Data/Functor";
import { List } from "./Data/List";
import { fromJust, isJust, Just } from "./Data/Maybe";
import { uncurryN } from "./Data/Pair";
import { uncurryN } from "./Data/Tuple/Curry";
import { Unit } from "./Data/Unit";
import { runIO } from "./System/IO";
+2 -1
View File
@@ -9,7 +9,7 @@ import { prerelease } from "semver";
import * as url from "url";
import { pipe_ } from "./App/Utilities/pipe";
import { tryIO } from "./Control/Exception";
import { fromLeft_, isLeft } from "./Data/Either";
import { fromLeft_, isLeft } from "./Data/Either/Extra";
import { fmap } from "./Data/Functor";
import { Unit } from "./Data/Unit";
import { existsFile, IO, join, liftM2, runIO, thenF } from "./System/IO";
@@ -56,6 +56,7 @@ const copyFileToCurrent =
(user_data_path)
function createWindow () {
console.log("test");
const mainWindowState = windowStateKeeper ({
defaultHeight: 720,
defaultWidth: 1280,
+1
View File
@@ -24,6 +24,7 @@
"rootDir": "src/",
"strict": true,
"skipLibCheck": true,
"sourceMap": true,
"target": "es2017"
},
"include": [