{- | Module : Language.Egison.MList Licence : MIT This module provides definition and utility functions for monadic list. -} module Language.Egison.MList ( MList (..) , fromList , fromSeq , fromMList , msingleton , mfoldr , mappend , mconcat , mmap , mfor , mAny ) where import Prelude hiding (mappend, mconcat,) import Data.Sequence (Seq) data MList m a = MNil | MCons a (m (MList m a)) instance Show a => Show (MList m a) where show MNil = "MNil" show (MCons x _) = "(MCons " ++ show x ++ " ...)" fromList :: Monad m => [a] -> MList m a fromList = foldr f MNil where f x xs = MCons x $ return xs fromSeq :: Monad m => Seq a -> MList m a fromSeq = foldr f MNil where f x xs = MCons x $ return xs fromMList :: Monad m => MList m a -> m [a] fromMList = mfoldr f $ return [] where f x xs = (x:) <$> xs msingleton :: Monad m => a -> MList m a msingleton = flip MCons $ return MNil mfoldr :: Monad m => (a -> m b -> m b) -> m b -> MList m a -> m b mfoldr _ init MNil = init mfoldr f init (MCons x xs) = f x (xs >>= mfoldr f init) mappend :: Monad m => MList m a -> m (MList m a) -> m (MList m a) mappend xs ys = mfoldr ((return .) . MCons) ys xs mconcat :: Monad m => MList m (MList m a) -> m (MList m a) mconcat = mfoldr mappend $ return MNil mmap :: Monad m => (a -> m b) -> MList m a -> m (MList m b) mmap f = mfoldr g $ return MNil where g x xs = flip MCons xs <$> f x mfor :: Monad m => MList m a -> (a -> m b) -> m (MList m b) mfor = flip mmap mAny :: Monad m => (a -> m Bool) -> MList m a -> m Bool mAny _ MNil = return False mAny p (MCons x xs) = do b <- p x if b then return True else do xs' <- xs mAny p xs'