Site updated at 2012-05-30 15:30:37 UTC

1 parent 0314676 commit bd6136c91f5cd135d70fcdb9cde57b20e2c0db19 MnO2 committed May 30, 2012
Showing with 21 additions and 16 deletions.
 @@ -64,8 +64,7 @@ ghci> runWriter (return 3 :: Writer (Sum Int) Int) (3,Sum {getSum = 0}) ghci> runWriter (return 3 :: Writer (Product Int) Int) -(3,Product {getProduct = 1})

Using do notation with Writer

{
+(3,Product {getProduct = 1})

Using do notation with Writer

logNumber :: Int -> Writer [String] Int
logNumber x = Writer (x, ["Got number: " ++ show x])
@@ -74,26 +73,32 @@
multWithLog = do
a <- logNumber 3
b <- logNumber 5
-    return (a*b)
-}

logNumber接受一個數並把這個數做成一個Writer

multWithLog式一個Writer

{
-ghci> runWriter multWithLog
-(15,["Got number: 3","Got number: 5"])
-}

tell正是我們需要的函數。

{
-multWithLog :: Writer [String] Int
+    return (a*b)

logNumber接受一個數並把這個數做成一個Writer

multWithLog式一個Writer

ghci> runWriter multWithLog
+(15,["Got number: 3","Got number: 5"])

tell正是我們需要的函數。

multWithLog :: Writer [String] Int
multWithLog = do
a <- logNumber 3
b <- logNumber 5
tell ["Gonna multiply these two"]
-    return (a*b)
-}

return (a*b)是我們的最後一行，

do的結果則會是()

{
-ghci> runWriter multWithLog
-(15,["Got number: 3","Got number: 5","Gonna multiply these two"])
-}

{
-gcd' :: Int -> Int -> Int
+    return (a*b)

return (a*b)是我們的最後一行，

do的結果則會是()

ghci> runWriter multWithLog
+(15,["Got number: 3","Got number: 5","Gonna multiply these two"])

gcd' :: Int -> Int -> Int
gcd' a b
| b == 0    = a
-    | otherwise = gcd' b (a `mod` b)
-}

ghci> let f = (*5)
+    | otherwise = gcd' b (a `mod` b)

ghci> gcd' 8 3
+1

context會是一個monoid value並且像是一個log一樣。

gcd' :: Int -> Int -> Writer [String] Int

+
+gcd' :: Int -> Int -> Writer [String] Int
+gcd' a b
+  | b == 0 = do
+      tell ["Finished with " ++ show a]
+      return a
+  | otherwise = do
+      tell [show a ++ " mod " ++ show b ++ " = " ++ show (a `mod` b)]
+      gcd' b (a `mod` b)

b等於0的時候，

Writer (a, ["Finished with " ++ show a])

gcd'現在是回傳一個Writer的型態，

tuple的第一個部份就是我們要的結果：

ghci> fst \$ runWriter (gcd' 8 3)
+1

ghci> mapM_ putStrLn \$ snd \$ runWriter (gcd' 8 3)
+8 mod 3 = 2
+3 mod 2 = 1
+2 mod 1 = 0
+Finished with 1

Inefficient list construction

ghci> let f = (*5)
ghci> let g = (+3)
ghci> (fmap f g) 8

ghci> let f = (+) <\$> (*2) <*> (+10)
ghci> f 3