{-# LANGUAGE
NoMonomorphismRestriction,
MultiParamTypeClasses,
FlexibleInstances
#-}
module List where
import Control.Monad.Sharing.Lazy
data List m a = Nil | Cons (m a) (m (List m a))
nil = return Nil
cons x xs = return (Cons x xs)
match n _ Nil = n
match _ c (Cons x xs) = c x xs
empty l = l >>= match (return True) (\_ _ -> return False)
first l = l >>= match mzero const
rest l = l >>= match mzero (flip const)
fold n c l = l >>= match n (\x xs -> c x (fold n c xs))
instance Nondet m a => Nondet m (List m a)
where
mapNondet _ Nil = return Nil
mapNondet f (Cons x xs) = do
y <- f x
ys <- f xs
return (Cons y ys)
instance MonadPlus m => Nondet m Int
where
mapNondet _ = return