[{"name":"Typed","comment":" Labelled wrapper\n\n@docs Typed\n\n\n## create\n\n@docs tag\n\n\n## creator\n\n@docs Tagged, Checked, toChecked\n\n\n## access\n\n\n### access public\n\n@docs Public, untag, toPublic\n\n\n### access internal\n\n@docs Internal, internal\n\n\n## transform\n\n@docs map, mapToTyped, mapTo, and\n\n\n## wrapping\n\nA pretty specialized use-case which helps using tags you don't have access to _inside your wrapper tag_\n\nExamples in the [version 8 announcement](https://github.com/lue-bird/elm-typed-value/blob/master/announcement.md#800)\n\n@docs mapToWrap, wrapToChecked\n@docs wrapToPublic, wrapInternal\n@docs wrapAnd\n\n","unions":[],"aliases":[{"name":"Checked","comment":" Only someone with access to the tag is able to create one of those.\n\nIn effect, this means that you can only let \"validated\" data be of this type.\n\nExample: `... Checked ... NaturalNumberTag Int`\n→ not every `Int` can be called a `NumberNatural`, it must be [checked](#toChecked)!\n\n","args":[],"type":"Typed.Internal.Checked"},{"name":"Internal","comment":" Only those with access to the tag can access the [`internal`](#internal) thing.\n\n→ access can be limited to\n\n  - inside a module\n\n        module Special exposing (Special)\n\n        type alias Special =\n            Typed Tagged SpecialTag Internal SpecialValue\n\n  - inside a package\n\n        Internal exposing (Tag(..))\n        A exposing (A)\n            import Internal exposing (Tag(..))\n        B exposing (B)\n            import Internal exposing (Tag(..))\n\n    ```json\n    'exposed-modules' : [ \"A\", \"B\" ]\n    ```\n\nThis in combination with [`Checked`](#Checked)\nhides the internals just like an opaque `type`\n\n    type alias ListOptimized element =\n        Typed\n            Checked\n            ListOptimizedTag\n            Internal\n            { list : List element, length : Int }\n\n    type ListOptimizedTag\n        = -- don't expose this variant\n          ListOptimizedTag\n\n","args":[],"type":"Typed.Internal.Internal"},{"name":"Public","comment":" Anyone is able to access the untyped thing\nof a [`Typed`](#Typed) `... Public`\nby using [`untag`](#untag)\n","args":[],"type":"Typed.Internal.Public"},{"name":"Tagged","comment":" Anyone is able to create a [`Typed`](#Typed) `Tagged ...`.\n\nExample: `Typed Tagged MetersTag ... Float`\n→ _every_ `Float` can be used as a quantity of `Meters`\n\n[`Typed`](#Typed) `Tagged ...` is also the result of trying to [`map`](#map) a [`Checked`](#Checked) thing\n\n    import Typed exposing (Typed, Checked, Public, tag)\n\n    type Prime\n        = Prime\n\n    prime3 : Typed Checked Prime Public Int\n    prime3 =\n        tag Prime 3\n\n    prime3\n        |> Typed.map (\\prime -> prime + 1) -- tee he\n    --: Typed Tagged Prime Public Int\n\n→ any function that only takes `Checked Prime` really only receives the good stuff\n\n","args":[],"type":"Typed.Internal.Tagged"},{"name":"Typed","comment":" A tagged thing.\n\n→ A `Typed ... Meters ... Float` isn't accepted as `Typed ... Kilos ... Float` anymore!\n\nFor a `type` with just 1 variant, a [`Typed`](#Typed) can be a safe replacement.\nIt'll save some boilerplate.\n\nA [`Typed`](#Typed) knows\n\n  - who has created it: [`Tagged`](#Tagged) | [`Checked`](#Checked)\n  - who can access it: [`Public`](#Public) | [`Internal`](#Internal)\n\nMore detailed explanations and examples\n→ [readme](https://dark.elm.dmy.fr/packages/lue-bird/elm-typed-value/latest/)\n\n\n### reading types\n\n    map :\n        (untyped -> untypedMapped)\n        -> Typed creator_ tag accessRight untyped\n        -> Typed Tagged tag accessRight untypedMapped\n\n  - works on any [`Typed`](#Typed)\n  - we can't be sure that the mapped thing can be considered [`Checked`](#Checked) → [`Tagged`](#Tagged)\n  - if the input is [`Public`](#Public) or [`Internal`](#Internal), the result will be the same\n\nNote: Just like with opaque types,\ncalling `==` is always possible,\neven on [`Internal`](#Internal) [`Typed`](#Typed)s\nto\n\n  - not lead to accidental crashes\n  - enable using it with the debugger\n  - allow storing it in a lamdera model/msg\n  - ...other stuff like testing becoming easier\n\nIf you really need to prevent users from finding out the inner thing without using [`untag`](#untag) or [`internal`](#internal), try\n\n  - → trick elm to always give `False` when checked for equality:\n      - `Typed ... ( thing, Unique )` with [`harrysarson/`: `Unique`](https://dark.elm.dmy.fr/packages/harrysarson/elm-hacky-unique/latest/)\n  - → cause elm to crash when checked for equality:\n      - `Typed ... (() -> thing)`\n      - `Typed ... ( thing, Json.Encode.Value )`\n      - `Typed ... ( thing, Regex )`\n      - ...\n\n","args":["creator","tag","accessRight","untyped"],"type":"Typed.Internal.Typed creator tag accessRight untyped"}],"values":[{"name":"and","comment":"\n\n> You can map, combine, ... even [`Internal`](#Internal) [`Typed`](#Typed)s\n> as long as a `Typed` with the **same tag & access rights** are returned in the end\n\n\n#### into [`map`](#map)\n\n    -- module Prime exposing (Prime, n3, n5)\n    import Typed exposing (Checked, Public, Typed, mapToTyped, tag)\n\n    type alias Prime =\n        Typed Checked PrimeTag Public Int\n\n    type PrimeTag\n        = Prime\n\n    n3 : Prime\n    n3 =\n        tag Prime 3\n\n    n5 : Prime\n    n5 =\n        tag Prime 5\n\n    -- module NonPrime exposing (NonPrime)\n    import Prime exposing (Prime)\n\n    type alias NonPrime =\n        Typed Checked NonPrimeTag Public Int\n\n    type NonPrimeTag\n        = NonPrime\n\n    fromMultiplyingPrimes : Prime -> Prime -> NonPrime\n    fromMultiplyingPrimes primeA primeB =\n        (primeA |> Typed.and primeB)\n            |> Typed.mapTo NonPrime (\\a b -> a * b)\n\n\n#### into [`mapToTyped`](#mapToTyped)\n\n    -- module Typed.Int\n\n    smaller : Typed create tag access Int -> Typed create tag access Int -> Typed create tag access Int\n    smaller =\n        \\int0Typed int1Typed ->\n            int0Typed\n                |> Typed.and int1Typed\n                |> Typed.mapToTyped\n                    (\\( int0, int1 ) ->\n                        if int0 <= int1 then\n                            int0Typed\n                        else\n                            -- int1 < int0\n                            int1Typed\n                    )\n\n    -- in another module\n\n    type OddTag\n        = Odd\n\n    smaller (Typed.tag Odd 3) (Typed.tag Odd 5)\n    --> Typed.tag Odd 3\n\n","type":"Typed.Typed nextCreator_ tag accessRight nextUntyped -> Typed.Typed creator_ tag accessRight untyped -> Typed.Typed Typed.Tagged tag accessRight ( untyped, nextUntyped )"},{"name":"internal","comment":" Only those who can show the tag\ncan access the [`Typed`](#Typed) [`Internal`](#Internal):\n\n    import Typed exposing (Checked, Internal, Typed)\n\n    type alias ListOptimized element =\n        Typed\n            Checked\n            ListOptimizedTag\n            Internal\n            -- optimizations might change in the future\n            { list : List element\n            , length : Int\n            }\n\n    type ListOptimizedTag\n        = ListOptimized\n\n    toList =\n        \\listOptimized ->\n            listOptimized\n                |> Typed.internal ListOptimized\n                |> .list\n\n    type ListOptimizedTag\n        = ListOptimized\n\n    equal =\n        \\( listOptimizedA, listOptimizedB ) ->\n            let\n                a =\n                    listOptimizedA |> Typed.internal ListOptimized\n\n                b =\n                    listOptimizedB |> Typed.internal ListOptimized\n            in\n            if a.length /= b.length then\n                False\n\n            else\n                a.list == b.list\n\n[`internal`](#internal) can be seen as\na shortcut for [`toPublic`](#toPublic), then [`untag`](#untag)\n\n    internal tag =\n        Typed.toPublic tag >> Typed.untag\n\n","type":"tag -> Typed.Typed creator_ tag accessRight_ untyped -> untyped"},{"name":"map","comment":" Change the untyped thing.\n\nThe result is not [`Checked`](#Checked),\nso it becomes just [`Tagged`](#Tagged)\n\n    import Typed exposing (Public, Tagged, Typed)\n\n    type alias Meters =\n        Typed Tagged MetersTag Public Int\n\n    add1km : Meters -> Meters\n    add1km =\n        Typed.map (\\m -> m + 1000)\n\nTo confirm that the [`map`](#map)s result is [`Checked`](#Checked)\n→ [`toChecked`](#toChecked)\n\n    import Typed exposing (Checked, Public, Typed)\n\n    type alias Odd =\n        Typed Checked OddTag Public Int\n\n    type OddTag\n        = Odd\n\n    next : Odd -> Odd\n    next =\n        \\odd ->\n            odd\n                |> Typed.map (\\m -> m + 2)\n                |> Typed.toChecked Odd\n\n","type":"(untyped -> mappedUntyped) -> Typed.Typed creator_ tag accessRight untyped -> Typed.Typed Typed.Tagged tag accessRight mappedUntyped"},{"name":"mapTo","comment":" [`map`](#map) which allows specifying a tag for the mapped result.\n\nRights of the result can be chosen by annotating or using it as\n\n  - [`Tagged`](#Tagged)/[`Checked`](#Checked)\n  - [`Internal`](#Internal)/[`Public`](#Public)\n\n```\nfromMultiplyingPrimes : Prime -> Prime -> NonPrime\nfromMultiplyingPrimes primeA primeB =\n    (primeA |> Typed.and primeB)\n        |> Typed.mapTo NonPrime (\\a b -> a * b)\n```\n\nIf the tag stays the same, just [`map`](#map)\nand if necessary add [`toChecked`](#toChecked)\n\n","type":"mappedTag -> (untyped -> mappedUntyped) -> Typed.Typed creator_ tag_ Typed.Public untyped -> Typed.Typed mappedCreatorChecked_ mappedTag mappedAccessRightPublic_ mappedUntyped"},{"name":"mapToTyped","comment":" Use the untyped thing to return a [`Typed`](#Typed)\nwith the **same tag & access right**\n\n    -- module Cat exposing (Cat, feed)\n    import Typed\n\n    type alias Cat =\n        Typed\n            Checked\n            CatTag\n            Internal\n            { mood : Mood, foodReserves : Float }\n\n    feed : Cat -> Cat\n    feed =\n        Typed.map\n            (\\cat ->\n                { cat | foodReserves = cat.foodReserves + 10 }\n            )\n\n    -- in another module\n    import Cat\n    import Typed\n\n    catOnUnhappyFeed : Cat -> Cat\n    catOnUnhappyFeed =\n        cat\n            |> Typed.mapToTyped\n                (\\catState ->\n                    case catState.mood of\n                        Unhappy ->\n                            cat |> Cat.feed\n\n                        Happy ->\n                            cat\n                )\n\nMap multiple arguments with [`and`](#and)\n\n","type":"(untyped -> Typed.Typed creatorMapped tag accessRight mappedUntyped) -> Typed.Typed creator_ tag accessRight untyped -> Typed.Typed creatorMapped tag accessRight mappedUntyped"},{"name":"mapToWrap","comment":" [`map`](#map), then put the existing tag after a given wrapper tag\n\n    type alias Hashing subject tag =\n        Typed Checked tag Public (subject -> Hash)\n\n    type Each\n        = Each\n\n    reverse :\n        Hashing element elementHashTag\n        -> Hashing (List element) ( Each, elementHashTag )\n    reverse elementHashing =\n        Typed.mapToWrap Each\n            (\\elementToHash ->\n                \\list ->\n                    list |> List.map elementToHash |> Hash.sequence\n            )\n            elementHashing\n\nUse [`wrapAnd`](#wrapAnd) to map multiple [`Typed`](#Typed)s\n\nThis doesn't violate any rules because you have no way of getting to the wrapped tag\n\n","type":"mappedTagWrap -> (untyped -> mappedUntyped) -> Typed.Typed creator_ tag Typed.Public untyped -> Typed.Typed mappedCreatorChecked_ ( mappedTagWrap, tag ) mappedAccessRightPublic_ mappedUntyped"},{"name":"tag","comment":" Create a new [`Typed`](#Typed) from its raw thing and the tag.\nRights can be chosen by annotating or using it as\n\n  - [`Tagged`](#Tagged)/[`Checked`](#Checked)?\n  - [`Internal`](#Internal)/[`Public`](#Public)?\n\n```\npasswordSafe =\n    tag NowItsSafe \"secret1234 th1s iS private oO\"\n\npasswordSafe |> Typed.untag\n--→ \"secret1234 th1s iS private oO\" oh no!\n```\n\ninstead\n\n    passwordSafe : Password -- important!\n    passwordSafe =\n        tag NowItsSafe \"secret1234 th1s iS private oO\"\n\n    passwordSafe |> Typed.untag\n    -- compile-time error\n\n    type alias Password =\n        Typed Checked PasswordTag Internal String\n\n    type PasswordTag\n        = NowItsSafe\n\n    passwordSafe |> Typed.internal NowItsSafe\n    --> \"secret1234 th1s iS private oO\"\n    -- allowed because we could prove we're in the internal module\n\n","type":"tag -> untyped -> Typed.Typed creatorChecked_ tag accessRightPublic_ untyped"},{"name":"toChecked","comment":" Confirm that it can be considered [`Checked`](#Checked) by supplying the matching tag.\nAnnotate or use the result as [`Tagged`](#Tagged)/[`Checked`](#Checked)\n\n    -- module Even exposing (Even, add, multiply)\n\n\n    import Typed exposing (Checked, Public, Typed)\n\n    type alias Even =\n        Typed Checked EvenTag Public Int\n\n    type EvenTag\n        = Even\n\n    multiply : Int -> Even -> Even\n    multiply factor =\n        \\even ->\n            even\n                |> Typed.map (\\int -> int * factor)\n                |> Typed.toChecked Even\n\n    add : Even -> Even -> Even\n    add toAddEven =\n        \\even ->\n            even\n                |> Typed.and toAddEven\n                |> Typed.map\n                    (\\( int, toAddInt ) -> int + toAddInt)\n                |> Typed.toChecked Even\n\nIf the tag should change after [`map`](#map), [`mapTo`](#mapTo)\n\n    oddAddOdd : Odd -> Odd -> Even\n    oddAddOdd oddToAdd =\n        \\odd ->\n            odd\n                |> Typed.and oddToAdd\n                -- ↓ same as mapTo Even (\\( o0, o1 ) -> o0 + 01)\n                |> Typed.map (\\( o0, o1 ) -> o0 + o1)\n                |> Typed.toChecked Even\n\n[`mapTo`](#mapTo) is better here since you don't have weird intermediate results like\n\n    odd\n        -- : Odd\n        |> Typed.and oddToAdd\n        |> Typed.map (\\( o0, o1 ) -> o0 + o1)\n        --: Typed Tagged OddTag Public Int\n        |> ...\n\n","type":"tag -> Typed.Typed creator_ tag accessRight untyped -> Typed.Typed creatorChecked_ tag accessRight untyped"},{"name":"toPublic","comment":" Confirm that it can be considered [`Public`](#Public) by supplying the matching tag.\nThe result can be annotated or used as [`Internal`](#Internal)/[`Public`](#Public)\n\n    internal tag =\n        toPublic tag >> untag\n\n","type":"tag -> Typed.Typed creator tag accessRight_ untyped -> Typed.Typed creator tag accessRightPublic_ untyped"},{"name":"untag","comment":" The thing inside the [`Typed`](#Typed) [`Public`](#Public)\n\n    -- module Prime exposing (Prime, n3, n5)\n\n    type alias Prime =\n        Typed Checked PrimeTag Public Int\n\n    type PrimeTag\n        = Prime\n\n    n3 : Prime\n    n3 =\n        3 |> tag Prime\n\n    n5 : Prime\n    n5 =\n        5 |> tag Prime\n\n    -- in another module using Prime\n    import Typed exposing (untag)\n\n    (n3 |> untag) < (n5 |> untag)\n    --> True\n\n","type":"Typed.Typed tag_ creator_ Typed.Public untyped -> untyped"},{"name":"wrapAnd","comment":" [`and`](#and) which keeps the tag from the first [`Typed`](#Typed) in the chain as the wrapping tag\n\n    type alias Hashing thing tag =\n        Typed Checked tag Public thing\n\n    type HashBy\n        = HashBy\n\n    hashBy :\n        Map mapTag (thing -> thingMapped)\n        -> Hashing thingHashingTag thingMapped\n        -> Hashing ( HashBy, ( mapTag, thingHashingTag ) ) thingMapped\n    hashBy map mappedHashing =\n        map\n            |> Typed.wrapAnd mappedHashing\n            |> Typed.mapToWrap HashBy\n                (\\( change, mappedHash ) ->\n                    \\toHash ->\n                        toHash |> change |> mappedHash\n                )\n\n","type":"Typed.Typed nextCreator_ tagFood Typed.Public nextUntyped -> Typed.Typed creator_ tagWrap accessRight untyped -> Typed.Typed Typed.Tagged ( tagWrap, tagFood ) accessRight ( untyped, nextUntyped )"},{"name":"wrapInternal","comment":" If you have a [`Typed`](#Typed) [`Internal`](#Internal),\nits untyped thing can't be read by everyone.\n\nIf you have access to the tag, you can access its untyped thing\n\n    run :\n        Typed Checked ( Hashing, thingTag ) Internal (thing -> Hash)\n        -> (thing -> Hash)\n    run hashing =\n        hashing |> Typed.wrapInternal Hashing\n\n[`internal`](#internal) can be seen as\na shortcut for [`wrapToPublic`](#wrapToPublic), then [`untag`](#untag)\n\n    internal tag =\n        Typed.wrapToPublic tag >> Typed.untag\n\n","type":"tagWrap -> Typed.Typed creator_ ( tagWrap, tagWrapped_ ) accessRight_ untyped -> untyped"},{"name":"wrapToChecked","comment":" Allow the creator to be [`Checked`](#Checked) by supplying the wrapper tag\n\n    type Reverse\n        = Reverse\n\n    Int.Order.increasing\n        |> reverse\n        --: Typed Checked ( Reverse, Int.Order.Increasing ) Public ...\n        |> Typed.map ...\n        --: Typed Tagged ( Reverse, Int.Order.Increasing ) Public ...\n        |> Typed.wrapToChecked Reverse\n    --: Typed Checked ( Reverse, Int.Order.Increasing ) Public ...\n\n","type":"tagWrap -> Typed.Typed creator_ ( tagWrap, tagWrapped ) accessRight untyped -> Typed.Typed creatorChecked_ ( tagWrap, tagWrapped ) accessRight untyped"},{"name":"wrapToPublic","comment":" Confirm that it can be considered [`Public`](#Public) by supplying the matching tag.\nThe result can be annotated or used as [`Internal`](#Internal)/[`Public`](#Public)\n\n    internal tag =\n        toPublic tag >> untag\n\n","type":"tagWrap -> Typed.Typed creator ( tagWrap, tagWrapped ) accessRight_ untyped -> Typed.Typed creator ( tagWrap, tagWrapped ) accessRightPublic_ untyped"}],"binops":[]}]