HOME | 7. ������ data �� class | Haskell �Τ��ٶ� | 9. õ�� | download | ���� |
Monad �ϼ¤Ϥ���ۤ�����ǰ�ǤϤ���ޤ��� "Haskell �� Monad ��Ȥäƻ���Ʃ�����������Ȥʤ� IO ��¸����Ƥ��롣" �Ȥ���������ʸ��䡢"Monad ������Τ������⤷��ʤ�" �ʤɤȤ������� �ˤ��ʤ��ǡ�Haskell 98 �ˤ���������ʬ����䤹���Ȼפ��ޤ���
��� Haskeller �� Monad ���Ȥ��������Ȥ���ޤ����� ����� Monad �����ΤǤϤʤ������Τ�äƤ��뤳�Ȥ��������Ǥ��� �ĤޤꡢMonad ��Ȥ��������Ȥ�����뤬��Monad ���Τ�Τ����櫓�ǤϤʤ� �Ȥ������ȤǤ���
����Ǥϡ�class Monad ������Ƥߤޤ��礦�����Τ褦�ˤʤäƤ��ޤ���
[code 1]
-- in predefined types and class
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
m >> k = m >>= \_ -> k
fail s = error s
[code 1] ���� class Monad �ˤ� 4 �Ĥ����δؿ�
(>>=), (>>), return, fail ��
���뤳�Ȥ�ʬ����ޤ����ޤ���
"class Monad m where" �Ȥ� "m a" ���Ȥ� "m b" �Ȥ��ä����Ҥ�
����Τǡ�
���������δؿ��� Maybe, List, IO �ʤɤβ���ʣ��Ū data ���˴ؤ����Τ���
�������ȡ�����ˡ�raturn �Ȥ� fail �Ȥ���ñ�줬�ߤ���Τǡ����Ԥ��뤫�⤷��ʤ�
���˴ؤ�äƤ���Ȥ������Ȥ�ʬ����ޤ�������ˡ�
(>>=) :: m a -> (a -> m b) -> m b���顢(>>=) �ϰ����Ȥ��ơ�
�����ơ�(>>) �ϡ�
m >> k = m >>= \_ -> k���顢m ���ͤ�ΤƤơ�k ��ƤӽФ��ؿ��Ǥ��뤳�Ȥ�ʬ����ޤ��� (Lisp �� progn �˻��Ƥ��ޤ���)
�ʾ�Τ��Ȥ��顢Monad �Ȥ����Τϼ��Ԥ��뤫�⤷��ʤ�����Ĥʤ���碌�� ���δؿ����Ǥ��뤳�Ȥ�ʬ����ޤ���
[code 2]
-- in standard-prelude
instance Monad Maybe where
(Just x) >>= k = k x
Nothing >>= k = Nothing
return = Just
fail s = Nothing
�Ĥޤꡢ�ʲ��Τ褦�ˤʤ�ޤ���
[example 1]
01: EasyMonad> s2i (0,"12345") 02: Just (1,"2345") 03: EasyMonad> s2i (1, "2345") 04: Just (12,"345")[code 3]
01: -- easy_monad.hs 02: -- a small script for haskell8.html 03: 04: module EasyMonad where 05: 06: import Char 07: 08: --- Let's convert a String to Int if the String is [0-9]+ 09: -- s2i is a (reading one character) function 10: s2i :: (Int, String) -> Maybe (Int, String) 11: s2i (i, "") = Just (i, "") 12: s2i (i, c:cs) | isDigit c = Just (i*10 + ord c - ord '0', cs) 13: | otherwise = Nothing 14: 15: -- same as s2i, written in Monadic term 16: s2i' :: (Int, String) -> Maybe (Int, String) 17: s2i' (i, "") = return (i, "") 18: s2i' (i, c:cs) | isDigit c = return (i*10 + ord c - ord '0', cs) 19: | otherwise = fail "The char is not Digit" 20: 21: -- whole function to convert string to Maybe Int 22: str2int :: String -> Maybe Int 23: str2int "" = Nothing 24: str2int str = iter (0, str) 25: where iter (i, "") = Just i 26: iter (i, cs) = let p = s2i (i, cs) 27: in if p == Nothing 28: then Nothing 29: else p >>= iter���Υ����ɤ���Ͽ�� easy_monad.hs �����äƤ���Τǡ������ hugs �ʤɤ�����Ū�ʽ����Ϥ� load ����[example 2] �Τ褦�ˤ���ͷ��ǤߤƤ��������� ʸ�����ɤ߹��ޤ�Ƥ����ͻҤ�(>>=) �λȤ�����ʬ����Ȼפ��ޤ���
[example 2]
EasyMonad> s2i (0, "123") -- read one Just (1,"23") EasyMonad> s2i (0, "123") >>= s2i -- read two Just (12,"3") EasyMonad> s2i (0, "123") >>= s2i >>= s2i -- read three Just (123,"") EasyMonad> s2i (0, "12a") >>= s2i >>= s2i -- I cannot convert "12a" into an Int Nothing EasyMonad> s2i (0, "abc") >>= s2i >>= s2i -- I cannot convert "abc" into an Int, either Nothings2i' (code 1, 16--19 ���ܡ� �� s2i �� Monad �Ѹ�ǽ�������ΤǤ�������Ʊ�ͤ�ư��ޤ���
str2int (code 1, 22--29 ���ܡˤ� s2i ���Ѥ��� String �� Maybe Int ���Ѵ����� �ؿ��Ǥ���
EasyMonad> str2int "12345" Just 12345 EasyMonad> str2int "12+345" Nothing�����㤫�� Monad ���ΤϤ���ʤ����ʤ����Ȥ����ꤤ���������Ȼפ��ޤ���
c1 >>= c2 >>= c3
�� (c1 >>= c2) >>= c3
�� c1 >>= (c2 >>= c3) (�� 1)
�� 1: ��Τϳ�ǰŪ�˽���Ρ�Haskell �Υ����ɤȤ��ƽ�
c1 >>= (\x -> c2 x >>= c3) ��
������ Monad ����Ȥ��� Monad §���������褦�ˤ��Ʋ�������
[Monad §]
return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= h��� Maybe �� Monad �� Monad §���������Ƥ��뤳�Ȥ��ǧ���Ƥߤޤ��礦��
-- Law 1 return x >>= k �� Just x >>= k �� k x -- Law 2 Just x >>= return �� return x �� Just x -- Law 3 Just y >>= (\x -> k x >>= h) �� (\x -> k x >>= h) y �� k y >>= h �� (Just y >>= k) >>= h
IO �η�̤�ؿ����Ϥ����� IO �� Monad ���������Ƥ��ޤ��� '...' ����ʬ�ϼ����˰�¸���ޤ���
instance Monad IO where (>>=) = ... return = ... fail s = ioError (userError s)
������ | ������ |
---|---|
do{foo} | foo |
do{foo; bazs} | foo >> do{bazs} |
do{let hoge; bazs} | let hoge in do{bazs} |
do{ p <- foo; bazs} | let ok p = do{bazs} ; ok _ = fail "..." in foo >>= ok |
�����ܤ�������§�� fail ���θ���Ƥ��뤿��츫�����ʬ����ˤ����ʤäƤ��ޤ�����
����Ū�ˤϰʲ��μ���Ʊ���Ǥ���
[������§ 4']
do{ p <- foo; bazs} �� foo >>= (\ p -> do{bazs})
�ʲ����̾�ε�ˡ�� do ��ˡ���Ѥ����������ץ��������ޤ���
01: -- simple echo 02: -- do notation 03: my_echo :: IO() 04: my_echo = do putStrLn "Enter something." 05: str <- getLine 06: putStrLn $ "You have entered: " ++ str 07: 08: -- conventional notation 09: my_echo' :: IO() 10: my_echo' = putStrLn "Enter something." >> 11: getLine >>= (\str -> putStrLn $ "You have entered: " ++ str)
instance Monad [] where m >>= k = concat (map k m) return x = [x] fail s = [](>>=) �� Maybe ���Ȥ����ְۤʤäƤ��ޤ��� List �ˤ����� (>>=) �ϡ��ꥹ�Ȥ��������Ƥ� k ����Ѥ����� ����� concat �ǤĤʤ���碌��Ȥ������ȤǤ��� �ޤ���return �ϥꥹ�Ȥ��뤳�ȡ� fail �϶��ꥹ�ȤǤ���
�ʲ��˥ꥹ�Ȥ����ǤΤ������������Ǥ���� c �ܤ���ؿ���
01: --- Monad at List 02: --- if odd then (*c) else fail 03: --- list notation 04: mul_odd1 :: Int -> [Int] -> [Int] 05: mul_odd1 c xs = xs >>= (\x -> if odd x 06: then [x*c] 07: else []) 08: 09: --- monadic notation 10: mul_odd2 :: Int -> [Int] -> [Int] 11: mul_odd2 c xs = xs >>= (\x -> if odd x 12: then return (x*c) 13: else fail "I like odd.") 14: 15: --- internal capsule 16: mul_odd3 :: Int -> [Int] -> [Int] 17: mul_odd3 c xs = [x*c | x <- xs, odd x]
EasyMonad> mul_odd2 10 [1,2,3,4,5] [10,30,50]
[���]
sequence :: Monad m => [m a] -> m [a]
sequence = foldr mcons (return [])
where mcons p q = p >>= \x -> q >>= \y -> return (x:y)
sequence_ :: Monad m => [m a] -> m ()
sequence_ = foldr (>>) (return ())
-- The xxxM functions take list arguments, but lift the function or
-- list element to a monad type
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f as = sequence (map f as)
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
mapM_ f as = sequence_ (map f as)
[��]
foo :: [Int] ->IO() foo = mapM_ print {- foo [1,2,3] �� sequence_ $ map print [1,2,3] �� sequence_ [(print 1), (print 2), (print 3)] �� print 1 >> print 2 >> print 3 -} baz :: [Double] -> Maybe [Double] baz xs = mapM bar xs where bar x = if x > 0 then return (sqrt x) else fail "I like positive." {- baz [1,4,9] �� sequence [Just 1.0, Just 2.0, Just 3.0] �� Just [1.0, 2.0, 3.0] baz [1,-4,9] �� sequence [Just 1.0, Nothing, Just 3.0] �� Nothing -}
HOME | 7. ������ data �� class | Haskell �Τ��ٶ� | 9. õ�� | download | ���� |