Skip to content

Commit

Permalink
Add (un)wrapFix/Mu/Nu
Browse files Browse the repository at this point in the history
  • Loading branch information
phadej authored and anton-k committed Apr 26, 2021
1 parent 1afbda0 commit 1e685ec
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.3.2

- Add `(un)wrapFix/Mu/Nu`

## 0.3.1

- Update bounds for GHC-9.0
Expand Down
2 changes: 1 addition & 1 deletion data-fix.cabal
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: data-fix
Version: 0.3.1
Version: 0.3.2
Cabal-Version: >= 1.10
License: BSD3
License-file: LICENSE
Expand Down
72 changes: 72 additions & 0 deletions src/Data/Fix.hs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,22 @@ module Data.Fix (
hoistFix',
foldFix,
unfoldFix,
wrapFix,
unwrapFix,
-- * Mu - least fixed point
Mu (..),
hoistMu,
foldMu,
unfoldMu,
wrapMu,
unwrapMu,
-- * Nu - greatest fixed point
Nu (..),
hoistNu,
foldNu,
unfoldNu,
wrapNu,
unwrapNu,
-- * Refolding
refold,
-- * Monadic variants
Expand Down Expand Up @@ -158,6 +164,28 @@ foldFix f = go where go = f . fmap go . unFix
unfoldFix :: Functor f => (a -> f a) -> a -> Fix f
unfoldFix f = go where go = Fix . fmap go . f

-- | Wrap 'Fix'.
--
-- >>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> wrapFix (Cons 10 x)
-- Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))))
--
-- @since 0.3.2
--
wrapFix :: f (Fix f) -> Fix f
wrapFix = Fix

-- | Unwrap 'Fix'.
--
-- >>> let x = unfoldFix (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> unwrapFix x
-- Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))
--
-- @since 0.3.2
--
unwrapFix :: Fix f -> f (Fix f)
unwrapFix = unFix

-------------------------------------------------------------------------------
-- Functor instances
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -275,6 +303,28 @@ foldMu f (Mu mk) = mk f
unfoldMu :: Functor f => (a -> f a) -> a -> Mu f
unfoldMu f x = Mu $ \mk -> refold mk f x

-- | Wrap 'Mu'.
--
-- >>> let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> wrapMu (Cons 10 x)
-- unfoldMu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
--
-- @since 0.3.2
--
wrapMu :: Functor f => f (Mu f) -> Mu f
wrapMu fx = Mu $ \f -> f (fmap (foldMu f) fx)

-- | Unwrap 'Mu'.
--
-- >>> let x = unfoldMu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> unwrapMu x
-- Cons 0 (unfoldMu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))
--
-- @since 0.3.2
--
unwrapMu :: Functor f => Mu f -> f (Mu f)
unwrapMu = foldMu (fmap wrapMu)

-------------------------------------------------------------------------------
-- Nu
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -320,6 +370,28 @@ foldNu f (Nu next seed) = refold f next seed
unfoldNu :: (a -> f a) -> a -> Nu f
unfoldNu = Nu

-- | Wrap 'Nu'.
--
-- >>> let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> wrapNu (Cons 10 x)
-- unfoldNu unFix (Fix (Cons 10 (Fix (Cons 0 (Fix (Cons 1 (Fix (Cons 2 (Fix Nil)))))))))
--
-- @since 0.3.2
--
wrapNu :: Functor f => f (Nu f) -> Nu f
wrapNu = unfoldNu (fmap unwrapNu)

-- | Unwrap 'Nu'.
--
-- >>> let x = unfoldNu (\i -> if i < 3 then Cons i (i + 1) else Nil) (0 :: Int)
-- >>> unwrapNu x
-- Cons 0 (unfoldNu unFix (Fix (Cons 1 (Fix (Cons 2 (Fix Nil))))))
--
-- @since 0.3.2
--
unwrapNu :: Functor f => Nu f -> f (Nu f)
unwrapNu (Nu f x) = fmap (Nu f) (f x)

-------------------------------------------------------------------------------
-- refold
-------------------------------------------------------------------------------
Expand Down

0 comments on commit 1e685ec

Please sign in to comment.