type DeltaLog = Writer [String] type DeltaWithLog = DeltaM DeltaLog returnW :: (Show a) => a -> DeltaLog a returnW x = do tell ([show x]) return x deltaAppend :: Delta a -> Delta a -> Delta a deltaAppend (Mono x) d = Delta x d deltaAppend (Delta x d) ds = Delta x (deltaAppend d ds) deltaFromList :: [a] -> Delta a deltaFromList = (foldl1 deltaAppend) . (fmap return) generatorM :: Int -> DeltaWithLog [Int] generatorM x = let intList = [1..x] in DeltaM (deltaFromList (fmap returnW (replicate 2 intList))) numberFilterM :: [Int] -> DeltaWithLog [Int] numberFilterM xs = let primeList = filter isPrime xs evenList = filter even xs in DeltaM (deltaFromList (fmap returnW [primeList, evenList])) countM :: [Int] -> DeltaWithLog Int countM xs = let numberCount = length xs in DeltaM (deltaFromList (fmap returnW (replicate 2 numberCount))) numberCountM :: Int -> DeltaWithLog Int numberCountM x = generatorM x >>= numberFilterM >>= countM