美文网首页Haskell
[Haskell] Monad

[Haskell] Monad

作者: 何幻 | 来源:发表于2016-03-04 07:15 被阅读87次
class Monad m where
return :: a -> m a

(>>=) :: m a -> (a -> m b) -> m b

(>>) :: m a -> m b -> m b
x >> y = x >>= \_ -> y

fail :: String -> m a
fail msg = error msg

Monad Law
(1)return x >>= f = f x
(2)m >>= return = m
(3)(m >>= f) >>= g = m >>= (\x -> f x >>= g)

注:
(1):k m = * -> *
(2)在do notation中模式匹配失败后,程序并不会crash,而是会调用函数fail。
(3)m a类型的值,称为monad value。

(1)Maybe是Monad类型类的实例

instance Monad Maybe where
return x = Just x
Nothing >>= f = Nothing
Just x >>= f = f x
fail _ = Nothing

我们看一下>>=是如何实例化的

(>>=) :: m a -> (a -> m b) -> m b
= Maybe a -> (a -> Maybe b) -> Maybe b

ghci> Just 9 >= \x -> return (x * 10)
Just 90

ghci> Nothing >>= \x -> return (x * 10)
Nothing

注:do notation

ghci> Just 3 >>= \x -> Just “!” >>= \y -> Just (show x ++ y)
Just “3!”

其中,

Just 3 >>= \x -> Just “!” >>= \y -> Just (show x ++ y)
= Just 3 >>= \x -> (Just “!” >>= \y -> Just ((show x) ++ y))
= Just 3   >>= \x ->
   Just “!” >>= \y ->
   Just (show x ++ y)
= do
   x <- Just 3
   y <- Just “!”
   Just (show x ++ y)

注:
(1)do表达式的结果是一个monad value。
(2)在do表达式中,如果某一行我们没有使用“<-”为monad value绑定值,就相当于使用了函数“>>”,表示不需要这个绑定值。((>>) :: x >> y = x >>= \_ -> y

do
    Just 1
    x <- Just 2
    Just x
= Just 1 >> Just 2 >>= \x -> Just x
= Just 1 >>= \_ -> Just 2 >>= \x -> Just x

(2)[]是Monad类型类的实例

instance Monad [] where
return x = [x]
xs >>= f = concat (map f xs)
fail _ = []
ghci> [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n, ch)
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

推导如下:

[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n, ch)
= concat $ map (\n -> ['a','b'] >>= \ch -> return (n, ch)) [1, 2]

(\n -> ['a','b'] >>= \ch -> return (n, ch)) 1
= ['a','b'] >>= \ch -> return (1, ch)
= concat $ map (\ch -> return (1, ch)) ['a','b']

(\ch -> return (n, ch)) 'a'
= return (1, 'a')
= [(1, 'a')]    (自动推导出类型`[(Int,Char)]`)

concat $ map (\ch -> return (1, ch)) ['a','b']
= concat [[(1, 'a')], [(1, 'b')]]
= [(1, 'a'), (1, 'b')]

concat $ map (\n -> ['a','b'] >>= \ch -> return (n, ch)) [1, 2]
= concat [[(1, 'a'), (1, 'b')], [(2, 'a'), (2, 'b')]]
= [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

写成do notation如下:

[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n, ch)
= do
n <- [1, 2]
ch <- ['a','b']
return (n, ch)

注: list comprehension

ghci> [(n, ch) | n <- [1, 2], ch <- ['a','b']]
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]

所以,list comprehension只是do notation的语法糖。

相关文章

  • Haskell学习-monad

    原文地址:Haskell学习-monad 什么是Monad Haskell是一门纯函数式的语言,纯函数的优点是安全...

  • [Haskell] Monad

    Monad Law(1)return x >>= f = f x(2)m >>= return = m(3)(m ...

  • 函数式内功心法-00: 万物互连之monad创世纪

    很多人学习haskell,都会在monad这个概念上迷失。真是天下苦monad久矣! 人们常常说 Monad不就是...

  • Reader Monad

    本文使用Haskell语言,并需要读者有Monad的基本概念 什么是Reader Monad 在介绍Reader之...

  • 关于Monad的一些误解

    从real world haskell中文版里摘录: 关于Monad的一些误解我们已经见识过很多Monad的例子并...

  • haskell的monad

  • [Haskell] State Monad

    1. 类型 类型用来区分内存中对程序员来说不同种类的数据块而内存中存储的是表达式的值所以,区分内存块的类型,就是...

  • 来看看几种 Monad

    来看看几种 Monad https://learnyoua.haskell.sg/content/zh-cn/ch...

  • 什么是Monad?

    最近比较巧合的接触了Functional programming,经常接触到Monad的概念(在Haskell和F...

  • Haskell中基于Monad的条件循环

    Haskell在Control.Monad库中提供了类似forM之类的普通循环计算功能,但是没有提供条件循环,但是...

网友评论

    本文标题:[Haskell] Monad

    本文链接:https://www.haomeiwen.com/subject/cpunkttx.html