Files
  • main.hs
main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import qualified Data.ByteString as B
import Data.Monoid
import qualified Control.Monad as CM
import qualified Control.Monad.Trans.Writer.Lazy as W
  
type Food = String  
type Price = Sum Int  
  
addDrink :: Food -> (Food,Price)  
addDrink "beans" = ("milk", Sum 25)  
addDrink "jerky" = ("whiskey", Sum 99)  
addDrink _ = ("beer", Sum 30) 


applyLog :: (Monoid m) => (a,m) -> (a -> (b,m)) -> (b,m) 
applyLog (x, log) f = (y, log `mappend` newLog)  
  where (y, newLog) = f x


something :: Int -> (Int, String)
something b = (b * 3, " world")

output :: String -> W.Writer [String] ()
output x = W.tell [x]


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


keepSmall :: Int -> W.Writer [String] Bool  
keepSmall x  
    | x < 4 = do  
        output ("Keeping " ++ show x)
        return True  
    | otherwise = do  
        output (show x ++ " is too large, throwing it away")
        return False  

powerset :: [a] -> [[a]]  
powerset xs = CM.filterM (\x -> [True, False]) xs  

binSmalls :: Int -> Int -> Either String Int  
binSmalls acc x  
    | x > 9     = Left ((show x) ++ " is too big")
    | otherwise = Right (acc + x)

main :: IO()
main = do
    mapM_ putStrLn $ snd $ W.runWriter (gcd' 8 3) 
    mapM_ putStrLn $ snd $ W.runWriter $ CM.filterM keepSmall [9,1,5,2,10,3] 
    putStrLn $ show $ CM.foldM binSmalls 0 [2,11,3,1]
    putStrLn $ show $ CM.foldM binSmalls 0 [2,8,3,1]
GHCi, version 8.6.3