[Haskell] Applicative

class (Functor f) = Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b

其中f并不是一个具体类型,而是一个单参类型构造器(:k f = * -> *)。f还必须首先是一个Functor。
类型f a的值称为applicative value。
<u></u>pure接受普通类型的值,返回包含这个普通类型值的applicative value。
<u></u><*>接受一个包含映射的applicative value,返回一个applicative value上的映射。

Applicative Law
(1)pure id <*> v = v
(2)pure (.) <*> u <*> v <*> w = u <*> (v <*> w)
(3)pure f <*> pure x = pure (f x)
(4)u <*> pure y = pure ($ y) <*> u

Examples

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

instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> somthing = fmap f something

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

(<*>) :: f (a -> b) -> f a -> f b
= Maybe (a -> b) -> Maybe a -> Maybe b

ghci> Just (+ 3) <*> Just 9
Just 12

ghci> pure (+) <*> Just 3 <*> Just 5
Just 8

注:
其中“<*>”是左结合的。

pure (+) <*> Just 3 <*> Just 5
= (pure (+) <*> Just 3) <*> Just 5
= (Just (+) <*> Just 3) <*> Just 5
= Just (3 +) <*> Just 5
= Just 8

所以,如果g是一个多参普通函数,xy...是包含普通值的applicative value,则
<u></u>pure g <*> x <*> y <*> ... 返回一个applicative value,它包含的值是,g作用于xy...包含的值的结果。

另外,我们看到,pure g <*> x = fmap g x
所以,pure g <*> x <*> y <*> ... = fmap g x <*> y <*> ...

我们定义:

(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x

因此,pure (+) <*> Just 3 <*> Just 5 = (+) <$> Just 3 <*> Just 5

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

instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]

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

(<*>) :: f (a -> b) -> f a -> f b
= [a -> b] -> [a] -> [b]

ghci> [(* 0), (+ 100), (^2)] <*> [1, 2, 3]
[0, 0, 0, 101, 102, 103, 1, 4, 9]

ghci> [(+), (*)] <*> [1, 2] <*> [3, 4]
[4, 5, 5, 6, 3, 4, 6, 8]

其中,

[(+), (*)] <*> [1, 2] <*> [3, 4]
= ([(+), (*)] <*> [1, 2]) <*> [3, 4]
= [(1 +), (2 +), (1 *), (2 *)] <*> [3, 4]
= [4, 5, 5, 6, 3, 4, 6, 8]

(3)IO是Applicative类型类的实例

instance Applicative IO where
pure = return
a <*> b = do
    f <- a
    x <- b
    return (f x)

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

(<*>) :: f (a -> b) -> f a -> f b
= IO (a -> b) -> IO a -> IO b

注:
(1)IO也是一个单参类型构造器(:k IO = * -> *)。
(2)IO String类型表示输出StringIO ()类型表示不输出。
(3)()是一个空tuple类型,这个类型只有一个值,即()
所以,()在不同的上下文中,既可以表示类型,也可以表示值。

(++) <$> getLine <*> getLine
= do
a <- getLine
b <- getLine
return $ a ++ b

其中getLine :: IO String

(4)(->) r是Applicative类型类的实例

instance Applicative ((->) r) where
pure x = \_ -> x
f <*> g = \x -> f x (g x)

我们看一下pure<*>是如何实例化的

pure :: a -> f a
= a -> ((-> r) a)
= a -> (r -> a)

(<*>) :: f (a -> b) -> f a -> f b
= ((->) r (a -> b)) -> ((->) r a) -> ((->) r b)
= (r -> a -> b) -> (r -> a) -> (r -> b)

ghci> (+) <$> (+ 3) <*> (* 100) $ 5
508

pure (+) <*> (+ 3)
= \_ -> (+) <*> (+ 3)
= \x -> (+) ((+ 3) x)
= \x -> ((x + 3) +)

pure (+) <*> (+ 3) <*> (* 100)
= \y -> ((y + 3) +) <*> (* 100)
= \x -> ((x + 3) +) (x * 100)
= \x -> (x + 3) + (x * 100)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容