[{"name":"Recursion","comment":" This module provides an abstraction over general recursion that allows the recursive computation\nto be executed without risk of blowing the stack.\n\nIf you are unfamiliar with why we need to be careful about unsafe recursion in Elm,\n[this article](https://functional-programming-in-elm.netlify.app/recursion/tail-call-elimination.html) describes the Tail-Call Elimination very well.\n\nIt is not terribly difficult to rewrite simple recursions to be safe by taking advantage of the Tail Call Optimization.\nHowever, the moment you need to recurse on two or more elements in a data structure it becomes quite hairy to write safely\nand the resulting code loses much of the beauty of recursion.\n\nThis module presents ways to create and execute the `Rec` monad, which is sufficiently powerful to represent non-simple recursion safely **and** will allow\nyou to preserve the recursive elegance that makes functional programming beautiful.\n\n\n## Core Type\n\n@docs Rec\n\n\n## Creating a `Rec`\n\n@docs base, recurse, recurseThen\n\n\n## Manipulating a `Rec`\n\n@docs map, andThen\n\nCheck out [`Recursion.Traverse`](https://package.elm-lang.org/packages/micahhahn/elm-safe-recursion/2.0.0/Recursion-Traverse)\nand [`Recursion.Fold`](https://package.elm-lang.org/packages/micahhahn/elm-safe-recursion/2.0.0/Recursion-Fold)\nfor helpers that work with containers of recursive types.\n\n\n## Running a `Rec`\n\n@docs runRecursion\n\n\n# Example\n\nImagine we have a generic binary tree type that we want to write a map function for:\n\n    type Tree a\n        = Leaf a\n        | Node (Tree a) (Tree a)\n\nThe standard recursive map algorithm is straightforward:\n\n    mapTree : (a -> b) -> Tree a -> Tree b\n    mapTree f tree =\n        case tree of\n            Leaf a ->\n                Leaf (f a)\n\n            Node l r ->\n                Node (mapTree f l) (mapTree f r)\n\n⚠️⚠️⚠️ This is unsafe! ⚠️⚠️⚠️\n\nSince the recursive calls to `mapTree` are not located in tail call position the Tail Call Optimization will not fire.\nWe are exposing ourselves to a crash if the tree is deep enough that we would have a stack overflow while executing it!\n\n\n## Using elm-safe-recursion\n\n    mapTree : (a -> b) -> Tree a -> Tree b\n    mapTree f initTree =\n        runRecursion\n            (\\tree ->\n                case tree of\n                    Leaf a ->\n                        base (Leaf (f a))\n\n                    Node l r ->\n                        recurseThen l\n                            (\\newL ->\n                                recurseThen r\n                                    (\\newR ->\n                                        baes <| Node newL newR\n                                    )\n                            )\n            )\n            initTree\n\n","unions":[{"name":"Rec","comment":" An opaque type representing a recursive computation.\n\n  - `r` is the **r**ecursive type.\n  - `t` is the **t**arget type that we are converting to.\n  - `a` is a type for intermediate parts of the computation.\n\nI think it is helpful to think of `Rec` like the `Promise` type in javascript. Simliar to a `Promise`, the\nresult in a `Rec` value might not be available yet because it needs to recursively evaluated in a separate step.\nSo instead of directly manipulating the value in a `Rec`, we instead can specify actions to be done with the value\nwhen it is available using `map` and `andThen`.\n\n","args":["r","t","a"],"cases":[]}],"aliases":[],"values":[{"name":"andThen","comment":" Apply a function to the result of a `Rec` computation that can specify more recursion.\n","type":"(a -> Recursion.Rec r t b) -> Recursion.Rec r t a -> Recursion.Rec r t b"},{"name":"base","comment":" The base case of a recursion. The value is injected directly into the `Rec` type.\n","type":"a -> Recursion.Rec r t a"},{"name":"map","comment":" Apply a function to the result of a `Rec` computation.\n","type":"(a -> b) -> Recursion.Rec r t a -> Recursion.Rec r t b"},{"name":"recurse","comment":" Recurse on a value.\n\nWhen the recursion is complete the `Rec` will contain a value of type `t`.\n\n","type":"r -> Recursion.Rec r t t"},{"name":"recurseThen","comment":" Recurse on a value and then take another action on the result.\n\nIf you find yourself writing code that looks like `recurse x |> andThen ...` or `recurse x |> map ...` you should\nconsider using `recurseThen` instead as it will be much more efficient.\n\n","type":"r -> (t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"runRecursion","comment":" Run a recursion given a function to run one layer and an initial value.\n","type":"(r -> Recursion.Rec r t t) -> r -> t"}],"binops":[]},{"name":"Recursion.Fold","comment":" This module contains functions for folding common collections types that can contain recursive data structures.\n\nPrefer to use the functions that accept a continuation when possible (`fold____Then`) as they will be more efficient than folding and then mapping after.\n\n\n# List\n\n@docs foldList, foldListThen\n@docs foldMapList, foldMapListThen\n\n\n# Dict\n\n@docs foldDict, foldDictThen\n@docs foldMapDict, foldMapDictThen\n\n\n# Array\n\n@docs foldArray, foldArrayThen\n@docs foldMapArray, foldMapArrayThen\n\n","unions":[],"aliases":[],"values":[{"name":"foldArray","comment":" Fold an `Array` whose items are recursive types.\n","type":"(t -> a -> a) -> a -> Array.Array r -> Recursion.Rec r t a"},{"name":"foldArrayThen","comment":" Fold an `Array` whose items are recursive types and then perform a recursive action with the result.\n","type":"(t -> a -> a) -> a -> Array.Array r -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"foldDict","comment":" Fold a `Dict` whose values are recursive types.\n\n    type HashTrie a\n        = Leaf a\n        | Node (Dict Char (HashTrie a))\n\n    countHashTrie : HashTrie a -> Int\n    countHashTrie =\n        runRecursion <|\n            \\tree ->\n                case tree of\n                    Leaf _ ->\n                        base 1\n\n                    Node trees ->\n                        foldDict (\\_ x count -> x + count) 0 trees\n\n","type":"(comparable -> t -> a -> a) -> a -> Dict.Dict comparable r -> Recursion.Rec r t a"},{"name":"foldDictThen","comment":" Fold a `Dict` whose values are recursive types and then perform a recursive action with the result.\n","type":"(comparable -> t -> a -> a) -> a -> Dict.Dict comparable r -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"foldList","comment":" Fold a list of items which are recursive types.\n\n    type RoseTree a\n        = Leaf a\n        | Node (List (RoseTree a))\n\n    countRoseTreeLeaves : RoseTree a -> Int\n    countRoseTreeLeaves =\n        runRecursion <|\n            \\tree ->\n                case tree of\n                    Leaf _ ->\n                        base 1\n\n                    Node trees ->\n                        foldList (+) 0 trees\n\n","type":"(t -> a -> a) -> a -> List.List r -> Recursion.Rec r t a"},{"name":"foldListThen","comment":" Fold a list of items which are recurisve types and then perform a recursive action with the result.\n","type":"(t -> a -> a) -> a -> List.List r -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"foldMapArray","comment":" Fold an `Array` whose items contain recursive types.\n","type":"(x -> a -> Recursion.Rec r t a) -> a -> Array.Array x -> Recursion.Rec r t a"},{"name":"foldMapArrayThen","comment":" Fold an `Array` whose items contain recursive types and then perform a recursive action with the result.\n","type":"(x -> a -> Recursion.Rec r t a) -> a -> Array.Array x -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"foldMapDict","comment":" Fold a `Dict` whose values contain recursive types.\n\n    type HashTrie a\n        = Leaf a\n        | Node (Dict Char ( Int, HashTrie a ))\n\n    countHashTrie : HashTrie a -> Int\n    countHashTrie =\n        runRecursion <|\n            \\tree ->\n                case tree of\n                    Leaf _ ->\n                        base 1\n\n                    Node trees ->\n                        foldMapDict (\\_ ( _, v ) count -> recurseMap v (\\x -> x + count)) 0 trees\n\n","type":"(comparable -> v -> a -> Recursion.Rec r t a) -> a -> Dict.Dict comparable v -> Recursion.Rec r t a"},{"name":"foldMapDictThen","comment":" Fold a `Dict` whose values contain recursive types and then perform a recursive action with the result.\n","type":"(comparable -> v -> a -> Recursion.Rec r t a) -> a -> Dict.Dict comparable v -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"foldMapList","comment":" Fold a list of items which contain recursive types.\n\n    type KeyedRoseTree a\n        = Leaf a\n        | Node (List ( String, KeyedRoseTree a ))\n\n    countRoseTreeLeaves : KeyedRoseTree a -> Int\n    countRoseTreeLeaves =\n        runRecursion <|\n            \\tree ->\n                case tree of\n                    Leaf _ ->\n                        base 1\n\n                    Node trees ->\n                        foldMapList\n                            (\\( _, rec ) count -> recurseMap rec ((+) count))\n                            0\n                            trees\n\n","type":"(x -> a -> Recursion.Rec r t a) -> a -> List.List x -> Recursion.Rec r t a"},{"name":"foldMapListThen","comment":" Fold a list of items which contain recursive types and then perform a recursive action with the result.\n","type":"(x -> a -> Recursion.Rec r t a) -> a -> List.List x -> (a -> Recursion.Rec r t b) -> Recursion.Rec r t b"}],"binops":[]},{"name":"Recursion.Traverse","comment":" This module provides traversals for common data structures that contain recursive types.\n\nPrefer to use the functions that accept a continuation when possible (`sequence____Then` or `traverse____Then`) as they will be more efficient than folding and then mapping after.\n\n\n### What is a traversal?\n\nA traversal is a transformation over a structure that **preserves the shape** of the structure.\nIn this module, the traversal functions allow us to convert from a structure containing recursive types into a recursive type containing the structure.\n\nIf you are trying to write a map function over a recursive data structure, a traversal is likely what you want.\n\n\n# List\n\n@docs sequenceList, sequenceListThen\n@docs traverseList, traverseListThen\n\n\n# Dict\n\n@docs sequenceDict, sequenceDictThen\n@docs traverseDict, traverseDictThen\n\n\n# Array\n\n@docs sequenceArray, sequenceArrayThen\n@docs traverseArray, traverseArrayThen\n\n\n# Maybe\n\n@docs sequenceMaybe, sequenceMaybeThen\n@docs traverseMaybe, traverseMaybeThen\n\n\n# Result\n\n@docs sequenceResult, sequenceResultThen\n@docs traverseResult, traverseResultThen\n\n","unions":[],"aliases":[],"values":[{"name":"sequenceArray","comment":" Traverse an `Array` where the values are recursive types.\n","type":"Array.Array r -> Recursion.Rec r t (Array.Array t)"},{"name":"sequenceArrayThen","comment":" Traverse an `Array` where the values are recursive types and then perform a recursive action on the result.\n","type":"Array.Array r -> (Array.Array t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"sequenceDict","comment":" Traverse a `Dict` where the values are recursive types.\n\n    type HashTrie a\n        = Leaf a\n        | Node (Dict Char (HashTrie a))\n\n    mapHashTrie : (a -> b) -> HashTrie a -> HashTrie b\n    mapHashTrie f =\n        runRecursion <|\n            \\tree ->\n                case tree of\n                    Leaf a ->\n                        base (Leaf (f a))\n\n                    Node dict ->\n                        sequenceDict dict\n                            |> map Node\n\n","type":"Dict.Dict comparable r -> Recursion.Rec r t (Dict.Dict comparable t)"},{"name":"sequenceDictThen","comment":" Traverse a `Dict` where the values are recursive types and then perform a recursive action on the result.\n","type":"Dict.Dict comparable r -> (Dict.Dict comparable t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"sequenceList","comment":" Traverse a list where the elements are recursive types.\n\n    type RoseTree a\n        = Node a (List (RoseTree a))\n\n    mapRoseTree : (a -> b) -> RoseTree a -> RoseTree b\n    mapRoseTree f =\n        runRecursion <|\n            \\(Node a nodes) ->\n                sequenceList nodes\n                    |> map (Node (f a))\n\n","type":"List.List r -> Recursion.Rec r t (List.List t)"},{"name":"sequenceListThen","comment":" Traverse a list where the elements are recursive types and then perform a recursive action on the result.\n","type":"List.List r -> (List.List t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"sequenceMaybe","comment":" Traverse a `Maybe` where the value might be a recursive type.\n\n    type NonEmpty a\n        = NonEmpty a (Maybe (NonEmpty a))\n\n    mapNonEmpty : (a -> b) -> NonEmpty a -> NonEmpty b\n    mapNonEmpty f =\n        runRecursion <|\n            \\(NonEmpty v maybe) ->\n                sequenceMaybe maybe\n                    |> map (NonEmpty (f v))\n\n","type":"Maybe.Maybe r -> Recursion.Rec r t (Maybe.Maybe t)"},{"name":"sequenceMaybeThen","comment":" Traverse a `Maybe` where the value might be a recursive type and then perform a recursive action on the result.\n","type":"Maybe.Maybe r -> (Maybe.Maybe t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"sequenceResult","comment":" Traverse a `Result` where the success value might be a recursive type.\n","type":"Result.Result e r -> Recursion.Rec r t (Result.Result e t)"},{"name":"sequenceResultThen","comment":" Traverse a `Result` where the success value might be a recursive type and then perform an action on the recursive result.\n","type":"Result.Result e r -> (Result.Result e t -> Recursion.Rec r t a) -> Recursion.Rec r t a"},{"name":"traverseArray","comment":" Traverse an `Array` where the values contain recursive types.\n","type":"(x -> Recursion.Rec r t a) -> Array.Array x -> Recursion.Rec r t (Array.Array a)"},{"name":"traverseArrayThen","comment":" Traverse an `Array` where the values contain recursive types and then perform a recursive action on the result.\n","type":"(x -> Recursion.Rec r t a) -> Array.Array x -> (Array.Array a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"traverseDict","comment":" Traverse a `Dict` where the values contain recursive types.\n","type":"(comparable -> v -> Recursion.Rec r t a) -> Dict.Dict comparable v -> Recursion.Rec r t (Dict.Dict comparable a)"},{"name":"traverseDictThen","comment":" Traverse a `Dict` where the values contain recursive types and then perform a recursive action the result.\n","type":"(comparable -> v -> Recursion.Rec r t a) -> Dict.Dict comparable v -> (Dict.Dict comparable a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"traverseList","comment":" Traverse a list where the elements contain recursive types.\n\n    type KeyedRoseTree a\n        = Node a (List ( String, KeyedRoseTree a ))\n\n    mapKeyedRoseTree : (a -> b) -> KeyedRoseTree a -> KeyedRoseTree b\n    mapKeyedRoseTree f =\n        runRecursion <|\n            \\(Node a nodes) ->\n                traverseList (\\( s, tree ) -> recurseMap tree (Tuple.pair s)) nodes\n                    |> map (Node (f a))\n\n","type":"(x -> Recursion.Rec r t a) -> List.List x -> Recursion.Rec r t (List.List a)"},{"name":"traverseListThen","comment":" Traverse a list where the elements contain recursive types and then perform a recursive action on the result.\n","type":"(x -> Recursion.Rec r t a) -> List.List x -> (List.List a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"traverseMaybe","comment":" Traverse a `Maybe` where the value might contain a recursive type.\n\n    type SeparatedList sep val\n        = SeparatedList val (Maybe ( sep, SeparatedList sep val ))\n\n    mapSeparatedList : (a -> b) -> SeparatedList sep a -> SeparatedList sep b\n    mapSeparatedList f =\n        runRecursion <|\n            \\(SeparatedList a maybeOthers) ->\n                maybeOthers\n                    |> traverseMaybe (\\( sep, sepList ) -> recurseMap sepList (Tuple.pair sep))\n                    |> map (SeparatedList (f a))\n\n","type":"(x -> Recursion.Rec r t a) -> Maybe.Maybe x -> Recursion.Rec r t (Maybe.Maybe a)"},{"name":"traverseMaybeThen","comment":" Traverse a `Maybe` where the value might contain a recursive type and then perform a recursive action on the result.\n","type":"(x -> Recursion.Rec r t a) -> Maybe.Maybe x -> (Maybe.Maybe a -> Recursion.Rec r t b) -> Recursion.Rec r t b"},{"name":"traverseResult","comment":" Traverse a `Result` where the success value might contain a recursive type.\n","type":"(v -> Recursion.Rec r t a) -> Result.Result e v -> Recursion.Rec r t (Result.Result e a)"},{"name":"traverseResultThen","comment":" Traverse a `Result` where the success value might contain a recursive type and then perform an action on the recursive result.\n","type":"(v -> Recursion.Rec r t a) -> Result.Result e v -> (Result.Result e a -> Recursion.Rec r t b) -> Recursion.Rec r t b"}],"binops":[]}]