-- | -- Module : Data.SubG.Unfold -- Copyright : (c) OleksandrZhabenko 2021 -- License : MIT -- Stability : Experimental -- Maintainer : olexandr543@yahoo.com -- -- Generalization of the 'Data.List.unfoldr' for the data type that has 'InsertLeft' and 'Monoid' instances. -- Inspired by: https://www.works-hub.com/learn/number-anamorphisms-aka-unfolds-explained-50e1a by Marty Stumpf. module Data.SubG.Unfold ( unfoldG , iterateG ) where import Data.SubG import Data.Maybe (isJust, fromJust) import Data.Monoid -- | Inspired by: https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.OldList.html#words -- and: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Also inspired by: https://www.works-hub.com/learn/number-anamorphisms-aka-unfolds-explained-50e1a by Marty Stumpf. -- Generalizes the 'Data.List.unfoldr' function not only for lists, but for the data type that has 'InsertLeft' and 'Monoid' instances. unfoldG :: (InsertLeft t a, Monoid (t a)) => (a -> Maybe (a, a)) -> a -> t a unfoldG :: (a -> Maybe (a, a)) -> a -> t a unfoldG a -> Maybe (a, a) p a x | Maybe (a, a) -> Bool forall a. Maybe a -> Bool isJust (a -> Maybe (a, a) p a x) = a x a -> t a -> t a forall (t :: * -> *) a. InsertLeft t a => a -> t a -> t a %@ (a -> Maybe (a, a)) -> a -> t a forall (t :: * -> *) a. (InsertLeft t a, Monoid (t a)) => (a -> Maybe (a, a)) -> a -> t a unfoldG a -> Maybe (a, a) p ((a, a) -> a forall a b. (a, b) -> b snd ((a, a) -> a) -> (a -> (a, a)) -> a -> a forall b c a. (b -> c) -> (a -> b) -> a -> c . Maybe (a, a) -> (a, a) forall a. HasCallStack => Maybe a -> a fromJust (Maybe (a, a) -> (a, a)) -> (a -> Maybe (a, a)) -> a -> (a, a) forall b c a. (b -> c) -> (a -> b) -> a -> c . a -> Maybe (a, a) p (a -> a) -> a -> a forall a b. (a -> b) -> a -> b $ a x) | Bool otherwise = t a forall a. Monoid a => a mempty -- | Inspired by: https://hackage.haskell.org/package/base-4.14.0.0/docs/src/Data.OldList.html#words -- and: Graham Hutton. A tutorial on the universality and expressiveness of fold. /J. Functional Programming/ 9 (4): 355–372, July 1999. -- that is available at the URL: https://www.cs.nott.ac.uk/~pszgmh/fold.pdf. -- Also inspired by: https://www.works-hub.com/learn/number-anamorphisms-aka-unfolds-explained-50e1a by Marty Stumpf. -- Generalizes the 'Prelude.iterate' function not only for lists, but for the data type that has 'InsertLeft' and 'Monoid' instances. iterateG :: (InsertLeft t a, Monoid (t a)) => (a -> a) -> a -> t a iterateG :: (a -> a) -> a -> t a iterateG a -> a f = (a -> Maybe (a, a)) -> a -> t a forall (t :: * -> *) a. (InsertLeft t a, Monoid (t a)) => (a -> Maybe (a, a)) -> a -> t a unfoldG (\a x -> (a, a) -> Maybe (a, a) forall a. a -> Maybe a Just (a x, a -> a f a x)) {-# INLINE iterateG #-}