haskell5.hs 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. module EsHs4 where
  2. import Control.Applicative
  3. import Control.Monad
  4. --Logger
  5. type Log = [String]
  6. newtype Logger a = Logger { runLogger :: (a, Log) }
  7. --Define an instance of Show for Logger
  8. instance Show a => Show (Logger a) where
  9. show (Logger a) = show a
  10. --Define an instance of Functor for logger
  11. class Functor f where
  12. fmap :: (a -> b) -> f a -> f b
  13. loggerMap :: ( a -> b) -> (Logger a) -> (Logger b)
  14. loggerMap f lg =
  15. let (v, l) = runLogger lg
  16. n = f v
  17. in Logger (n, l)
  18. instance Functor Logger where
  19. fmap = loggerMap
  20. loggerApp :: Logger (a -> b) -> Logger a -> Logger b
  21. loggerApp lf lg =
  22. let (f, s) runLogger lf
  23. nl = loggerMap f lg
  24. (n, l) = runLogger nl
  25. in Logger (n, l ++ s)
  26. instance Applicative Logger where
  27. pure a = Logger (a, [])
  28. (<*>) = loggerApp
  29. instance Monad Logger where
  30. m >>= f = let(a, w) = runLogger m
  31. n = f a
  32. (b, x) = runLogger n
  33. in Logger (b, w ++ x)
  34. --Define a function that takes a number, add one and log the op:
  35. logPlusOne :: (Num a) => a -> Logger a
  36. logPlusOne a = Logger (a+1, ["added one"])
  37. logMultiplyTwo :: (Num a) => a -> Logger a
  38. logMultiplyTwo = Logger (a*2, ["Multiplied by two"])
  39. --Define logOps
  40. logOps :: (Num a) => Logger a -> Logger a
  41. logOps lg = do
  42. v <- lg
  43. p1 <- logPlusOne v
  44. m2 <- logMultiplyTwo p1
  45. return m2
  46. -- Define a record function to record things in the log
  47. record :: String -> Logger()
  48. record s = Logger ((), [s])