盒子里的计算

如果我们要运算1+2的话我们直接写:1+2,这样就会返回结果3.

但是,如果我们要计算列表里面的数值怎么办呢?

例如:
我们想计算 [1] + [2],我们希望haskell能计算出的结果是[3],这时候<*>与<$>的作用就出来了,通过下面的表达式我们可以得到结果[3]

(+) <$> [1] <*> [2]

<$>会把(+)运算符变成列表内部的运算符,可以当作是一个柯里化后的函数(+) 1放入了列表变为[ (+ 1)]

<*>就会运算列表内的计算,计算出[(+1)] 与[2]的值


1、对<$>与<*>的理解

  • 函数组合
    (.) :: (b -> c) -> (a -> b) -> a -> c

  • 0优先级的函数应用
    ($) :: (a -> b) > a -> b

  • 帮助把函数应用到函子里的数据上
    (<$>) :: (a -> b) -> f a -> f b

  • 把函子里的函数应用到函子里的数据上
    (<*>) :: f (a -> b) -> f a -> f b


2、对(>>=)的理解

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

(>>=)运算符相当于把基于applicative类型类的monad类型类m a 中的各个元素a需出来,每个元素a运用一次(a -> m b)的函数得到一系列的m b,再通过二元运算符<*>,将各个m b接连成一个新的m b

例如:

> [1,2,3,4,5] >>= \x -> [x+1]
[2,3,4,5,6]

这里相当于将列表[1,2,3,4,5]中的各个元素1,2,3,4,5分别取出来,应用到函数(\x -> [x+1])上,分别得到[2],[3],[4],[5],[6],再通过列表的二元运算符(<*> = (++)),连接各个结果,得到最终的列表[2,3,4,5,6]


3、(-> r)的Monad实例

instance Monad (-> r) where
	(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
	f >>= g = \r -> g (f r) r

例如:

> (+1) >>= (*) >>= (-) $ 3
9

计算过程为: (相当于(3+1)*3-3)

	(+1) >>= (*) >>= (-) $ 3
= (\r -> (*) ((+1) r) r) >>= (-) $ 3
= (\r -> (-) ((\r -> (*) ((+1) r) r) >>= (-)) r)r)  $ 3
= (-) ((*) ((+1) 3) 3) 3
= (-) ((*) 4 3) 3
= (-) 12 3
= 9
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐