subG-0.5.0.0: Data/SubG/Unfold.hs
-- |
-- 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 p x
| isJust (p x) = x %@ unfoldG p (snd . fromJust . p $ x)
| otherwise = 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 f = unfoldG (\x -> Just (x, f x))
{-# INLINE iterateG #-}