簡體   English   中英

為什么fmap f xs =純f <*> xs?

[英]Why fmap f xs = pure f <*> xs?

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

“純”扮演兩個角色:
*具有0元函數時的簡並情況。
* fmap f xs =純f <*> xs

我不明白為什么

fmap f xs = pure f <*> xs

我的意思是pure應該取a並返回fa 但是pure f做什么? 甚至pure (f <*> xs)對我來說也是有意義的。

也許一個具體的例子是說明性的。 以適用列表為准。 <*>每個函數從其左側操作數應用於其右側的每個值:

fs <*> xs = [f x | f <- fs, x <- xs]

pure將值包裝在單例列表中:

pure (+ 1) = [(+ 1)]

因此, pure f <*> xs = fmap f xs ,因為<*>將每個函數(恰好只有一個)應用於每個值,而fmap將一個函數應用於每個值:

pure (+ 1) <*> [1, 2, 3]
=
[(+ 1)] <*> [1, 2, 3]
=
[f x | f <- [(+ 1)], x <- [1, 2, 3]]
=
[(+ 1) x | x <- 1, 2, 3]
=
[x + 1 | x <- 1, 2, 3]
=
[2, 3, 4]


fmap (+ 1) [1, 2, 3]
=
[(+ 1) x | x <- [1, 2, 3]]
=
[x + 1 | x <- [1, 2, 3]]
=
[2, 3, 4]

這也是<$><*>運算符如何共同作用,以對多個操作的結果應用多參數函數,例如:

(*) <$> [1..5] <*> [1..5]
=
((*) <$> [1..5]) <*> [1..5]
=
[(1 *), (2 *), (3 *), (4 *), (5 *)] <*> [1..5]
=
[ (1 *) 1, (2 *) 1, (3 *) 1, (4 *) 1, (5 *) 1
, (1 *) 2, (2 *) 2, (3 *) 2, (4 *) 2, (5 *) 2
, (1 *) 3, (2 *) 3, (3 *) 3, (4 *) 3, (5 *) 3
, (1 *) 4, (2 *) 4, (3 *) 4, (4 *) 4, (5 *) 4
, (1 *) 5, (2 *) 5, (3 *) 5, (4 *) 5, (5 *) 5
]
=
[ 1,  2,  3,  4,  5
, 2,  4,  6,  8, 10
, 3,  6,  9, 12, 15
, 4,  8, 12, 16, 20
, 5, 10, 15, 20, 25
]

也可以將其寫為pure (*) <*> [1..5] <*> [1..5]

<$>建立一個操作(在本例中為列表),該操作返回(包含)部分應用的函數,而<*>接受這些函數並將其應用於參數。 (並且,如果函數接受兩個以上的參數,那么這還可能導致部分應用的函數,而該函數可以通過<*>另一個應用程序應用於更多的參數。)

其他“類似容器的”應用程序(例如MaybeEither e (對於某些e ))以及“類似動作”的應用程序(例如IOCont rAsync

但是pure f做什么?

給定f :: a -> b ,我們得到pure f :: f (a -> b) ,最后一個f是任何應用函子。 這將創建一個正確類型的值作為第一個參數傳遞給

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

我的意思是說pure應該取a並返回fa

沒錯-在這種情況下, a你提到的是函數類型a -> b我上面提到的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM