简体   繁体   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

"pure" plays two roles: “纯”扮演两个角色:
* The degenerate case when you have a 0-ary function, kind of. *具有0元函数时的简并情况。
* fmap f xs = pure f <*> xs * fmap f xs =纯f <*> xs

I don't understand why 我不明白为什么

fmap f xs = pure f <*> xs

I mean pure should take any a and return fa . 我的意思是pure应该取a并返回fa But what does pure f do? 但是pure f做什么? Even pure (f <*> xs) makes sense to me. 甚至pure (f <*> xs)对我来说也是有意义的。

Maybe a concrete example would be illustrative. 也许一个具体的例子是说明性的。 Take the list applicative. 以适用列表为准。 <*> applies each function from its left operand to each value from its right: <*>每个函数从其左侧操作数应用于其右侧的每个值:

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

And pure wraps a value in a singleton list: pure将值包装在单例列表中:

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

So pure f <*> xs = fmap f xs , because <*> applies each function— of which there happens to be only one —to each value, while fmap applies one function to each value: 因此, 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]

This is also how the <$> and <*> operators work together to apply a multi-argument function over the results of multiple actions, eg: 这也是<$><*>运算符如何共同作用,以对多个操作的结果应用多参数函数,例如:

(*) <$> [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
]

This could also have been written pure (*) <*> [1..5] <*> [1..5] . 也可以将其写为pure (*) <*> [1..5] <*> [1..5]

<$> builds an action (in this case a list) returning (containing) partially applied functions, and <*> takes those functions and applies them to arguments. <$>建立一个操作(在本例中为列表),该操作返回(包含)部分应用的函数,而<*>接受这些函数并将其应用于参数。 (And if the function takes more than two arguments, then this may also result in partially applied functions, which can be applied to more arguments with another application of <*> .) (并且,如果函数接受两个以上的参数,那么这还可能导致部分应用的函数,而该函数可以通过<*>另一个应用程序应用于更多的参数。)

The same laws hold in other “container-like” applicatives such as Maybe or Either e (for some e ), as well as “action-like” applicatives such as IO , Cont r , or Async . 其他“类似容器的”应用程序(例如MaybeEither e (对于某些e ))以及“类似动作”的应用程序(例如IOCont rAsync

But what does pure f do? 但是pure f做什么?

Given, f :: a -> b , we obtain pure f :: f (a -> b) the last f being any applicative functor. 给定f :: a -> b ,我们得到pure f :: f (a -> b) ,最后一个f是任何应用函子。 This creates a value of the right type to pass as the first argument to 这将创建一个正确类型的值作为第一个参数传递给

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

I mean pure should take any a and return fa 我的意思是说pure应该取a并返回fa

Exactly -- in this case the a you mention is the function type a -> b I mentioned above. 没错-在这种情况下, a你提到的是函数类型a -> b我上面提到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 concatMap f xs和concat $ map f xs之间的区别? - Difference between concatMap f xs and concat $ map f xs? 手动推导`f1 x xs =(filter。(&lt;))x xs`的类型 - Manual derivation of the type for `f1 x xs = (filter . (<)) x xs` 为什么replicateM (length xs) m 比sequenceA (fmap (const m) xs) 更有效? - Why is replicateM (length xs) m way more efficient than sequenceA (fmap (const m) xs)? 如何创建函数迭代器xs f,其中xs是列表,f是Haskell中的单坐函数 - how to create a function iterator xs f where xs is a list and f is one-seated function in Haskell 这总是如此:fmap(foldr fz)。 sequenceA = foldr(liftA2 f)(纯z) - Is this always true: fmap (foldr f z) . sequenceA = foldr (liftA2 f) (pure z) 为什么`让foo =(fmap.const)`失败“因为使用`fmap&#39;而没有(Functor f0)的实例? - Why does `let foo = (fmap . const)` fail with “No instance for (Functor f0) arising from a use of `fmap'”? (\\ f - &gt; fmap f id)总是等同于arr吗? - Is (\f -> fmap f id) always equivalent to arr? Haskell函数组成与fmap f - Haskell function composition and fmap f 模式中的解析错误:f。 g在fmap中(f.g)= fmap f。 fmap g - Parse error in pattern: f . g in fmap (f . g) = fmap f . fmap g 如果f是a-&gt; b类型的函数,则(fmap f)与(f。)相同吗? - Is (fmap f) the same as (f .) if f is a function of type a->b?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM