-- Inspired by blaze2007@FuncProgram.smth.org data Id a = Id { unboxId :: a } deriving Show instance Monad Id where return = Id (Id x) >>= k = k x mfix f = (mfix f) `bind` f -- eager bind forces its first argument to match the pattern (Id x), thereby enforcing sequence where bind = (>>=) -- lazy bind delays the unboxing computation until needed -- where bind x k = k $ unboxId x -- or a lazy pattern match -- where bind ~(Id x) k = k x mrec f = return (\i -> if i == 0 then 1 else i * f (i - 1) ) mfac :: Id (Int -> Int) mfac = mfix mrec -- compute factorial main = print $ unboxId mfac 3