haskell5.hs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import Control.Applicative
  2. import Control.Monad
  3. import Control.Monad.State
  4. -- Logger
  5. type Log = [String]
  6. newtype Logger a = Logger {runLogger :: (a, Log)}
  7. --Let's define Log an instance of Show
  8. instance (Show a) => Show (Logger a ) where
  9. show (Logger a) = show a
  10. --Define an instance of Functor for Logger
  11. loggerMap :: (a -> b) -> Logger a -> Logger b
  12. loggerMap f lg =
  13. let (v, l) = runLogger lg
  14. n = f v
  15. in Logger (n, l)
  16. instance Functor Logger where
  17. fmap = loggerMap
  18. loggerApp :: Logger (a -> b) -> Logger a -> Logger b
  19. loggerApp lf lg =
  20. let (f, s) = runLogger lf
  21. nl = loggerMap f lg
  22. (n, l) = runLogger nl
  23. in Logger (n, l ++ s)
  24. instance Applicative Logger where
  25. pure x = Logger (x, [])
  26. (<*>) = loggerApp
  27. --Define the Logger Monad
  28. instance Monad Logger where
  29. m >>= f = let (a, w) = runLogger m
  30. n = f a
  31. (b, x) = runLogger n
  32. in Logger (b, w ++ x)
  33. --Define a function that takes a number, add one and log the operation
  34. logPlusOne :: (Num a) => a -> Logger a
  35. logPlusOne a = Logger (a+1, ["added one"])
  36. --Define a function that takes a number, doubles it and log the operation
  37. logMultiplyTwo :: (Num a) => a -> Logger a
  38. logMultiplyTwo a = Logger (a*2, ["Multiplied by two"])
  39. --Define a function that takes a logger, adds one, double the value and logs all the operations
  40. logOps :: (Num a) => a -> Logger a
  41. logOps a = pure a >>= logPlusOne >>= logMultiplyTwo
  42. logOps' :: (Num a) => Logger a -> Logger a
  43. logOps' a = do
  44. v <- a
  45. s1 <- logPlusOne v
  46. p2 <- logMultiplyTwo s1
  47. return p2
  48. --Define a record function to record things in the logPlusOne
  49. record :: String -> Logger ()
  50. record s = Logger ((), [s])
  51. --Define a binary Tree
  52. data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Eq, Read)
  53. treeFoldr :: (b -> a -> a) -> a -> Tree b -> a
  54. treeFoldr f acc EmptyTree = acc
  55. treeFoldr f acc (Node a left right) = treeFoldr f (f a (treeFoldr f acc right)) left
  56. singletonM :: (Show a) => a -> Logger (Tree a)
  57. singletonM x = do
  58. record ("Created singleton" ++ show x)
  59. return (Node x EmptyTree EmptyTree)
  60. treeInsertM :: (Ord a, Show a) => Tree a -> a -> Logger (Tree a)
  61. treeInsertM EmptyTree x = singletonM x
  62. treeInsertM (Node a left right) x
  63. | x == a = do
  64. record("Inserted " ++ show x)
  65. return (Node x left right)
  66. | x < a = do
  67. l <- treeInsertM left x
  68. return (Node a l right)
  69. | x > a = do
  70. r <- treeInsertM right x
  71. return (Node a left r)
  72. treeSumM :: (Num a) => Logger (Tree a) -> Logger a
  73. treeSumM t = fmap (treeFoldr (+) 0) t
  74. andM :: Logger Bool -> Logger Bool -> Logger Bool
  75. andM log1 log2 = do
  76. c1 <- log1
  77. c2 <- log2
  78. return (c1 && c2)
  79. treeBalancedM :: Tree a -> Logger Bool
  80. treeBalancedM EmptyTree = do
  81. record "an empty tree is always balanced"
  82. return True
  83. treeBalancedM (Node _ EmptyTree EmptyTree) = do
  84. record "A single node tree is always balanced"
  85. return True
  86. treeBalancedM (Node _ EmptyTree _) = do
  87. record "Unbalanced"
  88. return False
  89. treeBalancedM (Node _ _ EmptyTree) = do
  90. record "Unbalanced"
  91. return False
  92. treeBalancedM (Node _ left right) = andM (treeBalancedM left) (treeBalancedM right)
  93. type Stack = [Int]
  94. --Define the pop function
  95. pop :: Stack -> (Int, Stack)
  96. pop (x:xs) = (x, xs)
  97. --Define the push function
  98. push :: Int -> Stack -> ((), Stack)
  99. push x xs = ((), x:xs)
  100. stackManip :: Stack -> (Int, Stack)
  101. stackManip stack = let
  102. (a, stack1) = pop stack
  103. (b, stack2) = pop stack1
  104. ((), stack3) = push 100 stack2
  105. (c, stack4) = pop stack3
  106. in pop stack4
  107. popM :: State Stack Int
  108. popM = do
  109. x:xs <- get
  110. put xs
  111. return x