diff --git a/src/Data/Unfoldable.purs b/src/Data/Unfoldable.purs index 68930a1..a241941 100644 --- a/src/Data/Unfoldable.purs +++ b/src/Data/Unfoldable.purs @@ -24,12 +24,27 @@ import Partial.Unsafe (unsafePartial) -- | This class identifies (possibly empty) data structures which can be -- | _unfolded_. -- | +-- | Just as `Foldable` structures can be collapsed to a single value with +-- | `foldl` and a provided _folding_ function, `unfoldr` allows generating +-- | an `Unfoldable` structure from a provided _unfolding_ function and an +-- | initial seed value. +-- | -- | The generating function `f` in `unfoldr f` is understood as follows: -- | -- | - If `f b` is `Nothing`, then `unfoldr f b` should be empty. -- | - If `f b` is `Just (Tuple a b1)`, then `unfoldr f b` should consist of `a` -- | appended to the result of `unfoldr f b1`. -- | +-- | For example: +-- | ``` purescript +-- | f :: Int -> Maybe (Tuple Int Int) +-- | f n | n < 0 = Nothing +-- | f n = Just (Tuple n (n - 1)) +-- | +-- | unfoldr f 3 == [3, 2, 1, 0] +-- | unfoldr f 3 == 3 : 2 : 1 : 0 : Nil +-- | ``` +-- | -- | Note that it is not possible to give `Unfoldable` instances to types which -- | represent structures which are guaranteed to be non-empty, such as -- | `NonEmptyArray`: consider what `unfoldr (const Nothing)` should produce. @@ -55,10 +70,10 @@ foreign import unfoldrArrayImpl -> Array a -- | Replicate a value some natural number of times. --- | For example: -- | -- | ``` purescript --- | replicate 2 "foo" == (["foo", "foo"] :: Array String) +-- | replicate 2 "foo" == ["foo", "foo"] +-- | replicate 2 "foo" == "foo" : "foo" : Nil -- | ``` replicate :: forall f a. Unfoldable f => Int -> a -> f a replicate n v = unfoldr step n @@ -73,6 +88,8 @@ replicate n v = unfoldr step n -- | ``` purescript -- | > replicateA 5 (randomInt 1 10) :: Effect (Array Int) -- | [1,3,2,7,5] +-- | > replicateA 5 (randomInt 1 10) :: _ (List _) +-- | (4 : 4 : 9 : 8 : 1 : Nil) -- | ``` replicateA :: forall m f a @@ -85,10 +102,11 @@ replicateA replicateA n m = sequence (replicate n m) -- | The container with no elements - unfolded with zero iterations. --- | For example: -- | -- | ``` purescript -- | none == ([] :: Array Unit) +-- | none == ([] :: _ Int) +-- | none == (Nil :: _ Number) -- | ``` none :: forall f a. Unfoldable f => f a none = unfoldr (const Nothing) unit @@ -98,6 +116,7 @@ none = unfoldr (const Nothing) unit -- | ``` purescript -- | fromMaybe (Nothing :: Maybe Int) == [] -- | fromMaybe (Just 1) == [1] +-- | fromMaybe (Just 1) == 1 : Nil -- | ``` fromMaybe :: forall f a. Unfoldable f => Maybe a -> f a fromMaybe = unfoldr (\b -> flip Tuple Nothing <$> b) diff --git a/src/Data/Unfoldable1.purs b/src/Data/Unfoldable1.purs index 6e4667b..3a59149 100644 --- a/src/Data/Unfoldable1.purs +++ b/src/Data/Unfoldable1.purs @@ -19,6 +19,19 @@ import Partial.Unsafe (unsafePartial) -- | operation of a non-empty list or array; it always returns a value, and -- | then optionally a value to continue unfolding from. -- | +-- | For example: +-- | ``` purescript +-- | g :: Int -> Tuple Int (Maybe Int) +-- | g n | n <= 0 = Tuple 0 Nothing +-- | g n = Tuple n (Just (n - 1)) +-- | +-- | unfoldr1 g 3 == NEA.cons' 3 [2, 1, 0] +-- | unfoldr1 g 3 == NEL.cons' 3 (2 : 1 : 0 : Nil) +-- | -- Also produces structures of types which can be empty +-- | unfoldr1 g 3 == [3, 2, 1, 0] +-- | unfoldr1 g 3 == 3 : 2 : 1 : 0 : Nil +-- | ``` +-- | -- | Note that, in order to provide an `Unfoldable1 t` instance, `t` need not -- | be a type which is guaranteed to be non-empty. For example, the fact that -- | lists can be empty does not prevent us from providing an @@ -58,8 +71,14 @@ foreign import unfoldr1ArrayImpl -- | `n` less than 1 will be treated as 1. -- | -- | ``` purescript --- | replicate1 2 "foo" == (NEL.cons "foo" (NEL.singleton "foo") :: NEL.NonEmptyList String) --- | replicate1 0 "foo" == (NEL.singleton "foo" :: NEL.NonEmptyList String) +-- | > replicate1 2 "foo" :: NonEmptyList _ +-- | (NonEmptyList (NonEmpty "foo" ("foo" : Nil))) +-- | > replicate1 0 "foo" :: NonEmptyArray _ +-- | (NonEmptyArray ["foo"]) +-- | > replicate1 0 "foo" :: List _ +-- | ("foo" : Nil) +-- | > replicate1 2 "foo" :: Array _ +-- | ["foo","foo"] -- | ``` replicate1 :: forall f a. Unfoldable1 f => Int -> a -> f a replicate1 n v = unfoldr1 step (n - 1) @@ -73,10 +92,10 @@ replicate1 n v = unfoldr1 step (n - 1) -- | than 1 will be treated as 1), and accumulate the results. -- | -- | ``` purescript --- | > replicate1A 2 (randomInt 1 10) :: Effect (NEL.NonEmptyList Int) +-- | > replicate1A 2 (randomInt 1 10) :: Effect (NonEmptyList Int) -- | (NonEmptyList (NonEmpty 8 (2 : Nil))) --- | > replicate1A 0 (randomInt 1 10) :: Effect (NEL.NonEmptyList Int) --- | (NonEmptyList (NonEmpty 4 Nil)) +-- | > replicate1A 0 (randomInt 1 10) :: _ (NonEmptyArray _) +-- | (NonEmptyArray [3]) -- | ``` replicate1A :: forall m f a @@ -91,7 +110,8 @@ replicate1A n m = sequence1 (replicate1 n m) -- | Contain a single value. For example: -- | -- | ``` purescript --- | singleton "foo" == (NEL.singleton "foo" :: NEL.NonEmptyList String) +-- | singleton "foo" == (NEL.singleton "foo" :: NonEmptyList String) +-- | singleton "foo" == (NEA.singleton "foo" :: NonEmptyArray String) -- | ``` singleton :: forall f a. Unfoldable1 f => a -> f a singleton = replicate1 1 @@ -103,6 +123,8 @@ singleton = replicate1 1 -- | range 0 0 == (NEL.singleton 0 :: NEL.NonEmptyList Int) -- | range 1 2 == (NEL.cons 1 (NEL.singleton 2) :: NEL.NonEmptyList Int) -- | range 2 0 == (NEL.cons 2 (NEL.cons 1 (NEL.singleton 0)) :: NEL.NonEmptyList Int) +-- | range 1 3 == [1, 2, 3] +-- | range 1 3 == 1 : 2 : 3 : Nil -- | ``` range :: forall f. Unfoldable1 f => Int -> Int -> f Int range start end =