{-# LANGUAGE InstanceSigs, ScopedTypeVariables, MultiParamTypeClasses, FlexibleInstances #-} -- reviewed HW5, HW6. data Cont r a = CT ((a -> r) -> r) runCont :: Cont r a -> (a -> r) -> r runCont (CT g) = g instance Functor (Cont r) where fmap :: (a -> b) -> Cont r a -> Cont r b fmap f (CT c) = CT $ \ k -> c (\ x -> k (f x)) instance Applicative (Cont r) where instance Monad (Cont r) where return :: a -> Cont r a return x = CT $ \ k -> k x (>>=) :: Cont r a -> (a -> Cont r b) -> Cont r b CT g >>= f = CT $ \ k -> g (\ x -> let CT h = f x in h k) fac :: Int -> Int fac 0 = 1 fac n | n > 0 = n * fac (n-1) fac' :: Int -> Cont r Int fac' 0 = return 1 fac' n | n > 0 = do r <- fac' (n-1) return (n * r) fac'' :: Int -> (Int -> r) -> r fac'' 0 k = k 1 fac'' n k | n > 0 = fac'' (n-1) (\ x -> k (n * x))