unfoldl package:ranged-list

To eveluate function repeatedly to construct a list of type LengthR n a. The function recieve a state and return a new state and an element value.
>>> :set -XDataKinds

>>> unfoldl (\n -> (n + 1, 2 * n)) 0 :: LengthR 5 Integer
((((NilR :+ 8) :+ 6) :+ 4) :+ 2) :+ 0
It is like unfoldl. But it use monad as an argument instead of function.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n <$ writeIORef r (n + 1)

>>> unfoldlM count :: IO (LengthR 5 Integer)
((((NilR :+ 5) :+ 4) :+ 3) :+ 2) :+ 1
It is like unfoldlM. But it has already prepared values.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n <$ writeIORef r (n + 1)

>>> unfoldlMWithBase count (NilR :++ 123 :+ 456) :: IO (LengthR 5 Integer)
((((NilR :+ 3) :+ 2) :+ 1) :+ 123) :+ 456
It is like unfoldl. But it has already prepared values.
>>> :set -XDataKinds

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Integer

>>> unfoldlWithBase (\n -> (n + 1, 2 * n)) 0 xs :: LengthR 5 Integer
((((NilR :+ 4) :+ 2) :+ 0) :+ 123) :+ 456
It is like unfoldlMax. But it uses a monad instead of function.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> unfoldlMMax count :: IO (RangeR 3 5 Integer)
((((NilR :++ 15) :++ 12) :+ 9) :+ 6) :+ 3
It is like unfoldlMax. But it uses a monad instead of a function.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> unfoldlMMin count :: IO (RangeR 3 5 Integer)
((NilR :+ 9) :+ 6) :+ 3
It is like unfoldlRange. But it use a monad instead of a function.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> unfoldlMRange ((< 5) <$> readIORef r) count :: IO (RangeR 3 5 Integer)
(((NilR :++ 12) :+ 9) :+ 6) :+ 3
It is like unfoldlRangeMaybe. But it use a monad instead of a function. The first argument monad returns a boolean value. It creates values while this boolean value is True. If this boolean value is False before to create enough values or True after to create full values, then unfoldlMRangeMaybe returns Nothing.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> check n0 = (< n0) <$> readIORef r

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> unfoldlMRangeMaybe (check 2) count :: IO (Maybe (RangeR 3 5 Integer))
Nothing
>>> writeIORef r 1

>>> unfoldlMRangeMaybe (check 5) count :: IO (Maybe (RangeR 3 5 Integer))
Just ((((NilR :++ 12) :+ 9) :+ 6) :+ 3)
>>> writeIORef r 1

>>> unfoldlMRangeMaybe (check 10) count :: IO (Maybe (RangeR 3 5 Integer))
Nothing
It is like unfoldrMRangeMaybe. But it has already prepared values.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> check = (< 3) <$> readIORef r

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Integer

>>> :{
unfoldlMRangeMaybeWithBase check count xs
:: IO (Maybe (RangeR 3 5 Integer))
:}
Just ((((NilR :++ 6) :+ 3) :+ 123) :+ 456)
It is like unfoldlMRange. But it has already prepared values.
>>> :set -XDataKinds

>>> :module + Data.IORef

>>> r <- newIORef 1

>>> count = readIORef r >>= \n -> n * 3 <$ writeIORef r (n + 1)

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Integer

>>> :{
unfoldlMRangeWithBase ((< 3) <$> readIORef r) count xs
:: IO (RangeR 3 5 Integer)
:}
(((NilR :++ 6) :+ 3) :+ 123) :+ 456
To eveluate a function to construct values maximum number of times. The function recieves a state and return a value and a new state.
>>> :set -XDataKinds

>>> unfoldlMax (\n -> (n + 1, n * 3)) 1 :: RangeR 3 5 Integer
((((NilR :++ 15) :++ 12) :+ 9) :+ 6) :+ 3
To evaluate a function to construct values minimum number of times. The function recieves a state and return a value and a new state.
>>> :set -XDataKinds

>>> unfoldlMin (\n -> (n + 1, n * 3)) 1 :: RangeR 3 5 Integer
((NilR :+ 9) :+ 6) :+ 3
To eveluate a function to construct a list. The function recieve a state and return an element and a new state. The first argument is a predication which is evaluated when an element number is greater than a minimum and not greater than a maximum.
>>> :set -XDataKinds

>>> unfoldlRange (< 2) (\n -> (n + 1, n * 3)) 1 :: RangeR 3 5 Int
((NilR :+ 9) :+ 6) :+ 3
>>> unfoldlRange (< 5) (\n -> (n + 1, n * 3)) 1 :: RangeR 3 5 Int
(((NilR :++ 12) :+ 9) :+ 6) :+ 3
>>> unfoldlRange (< 10) (\n -> (n + 1, n * 3)) 1 :: RangeR 3 5 Int
((((NilR :++ 15) :++ 12) :+ 9) :+ 6) :+ 3
To evaluate a function to construct a list. The function recieves a state and return a nothing value or an element and a new state. If the number of created elements is less than a minimum number of list elements or greater than a maximum number, then return Nothing.
>>> :set -XDataKinds

>>> count n0 n = if n < n0 then Just (n + 1, n * 3) else Nothing

>>> unfoldlRangeMaybe (count 2) 1 :: Maybe (RangeR 3 5 Int)
Nothing
>>> unfoldlRangeMaybe (count 5) 1 :: Maybe (RangeR 3 5 Int)
Just ((((NilR :++ 12) :+ 9) :+ 6) :+ 3)
>>> unfoldlRangeMaybe (count 10) 1 :: Maybe (RangeR 3 5 Int)
Nothing
It is like unfoldlRangeMaybe. But it has already prepared values.
>>> :set -XDataKinds

>>> count n = if n < 3 then Just (n + 1, n * 3) else Nothing

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Int

>>> unfoldlRangeMaybeWithBase count 1 xs :: Maybe (RangeR 3 5 Int)
Just ((((NilR :++ 6) :+ 3) :+ 123) :+ 456)
It is like unfoldlRange. But it has already prepared values.
>>> :set -XDataKinds

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Integer

>>> unfoldlRangeWithBase (< 3) (\n -> (n + 1, n * 3)) 1 xs :: RangeR 3 5 Integer
(((NilR :++ 6) :+ 3) :+ 123) :+ 456
It is like unfoldlRangeWithBase. But it return not only a list but also a state value.
>>> :set -XDataKinds -fno-warn-tabs

>>> xs = NilR :++ 123 :+ 456 :: RangeR 1 5 Integer

>>> :{
unfoldlRangeWithBaseWithS (< 3) (\n -> (n + 1, n * 3)) 1 xs
:: (Integer, RangeR 3 5 Integer)
:}
(3,(((NilR :++ 6) :+ 3) :+ 123) :+ 456)