简体   繁体   English

简单的应用函数示例

[英]Simple Applicative Functor Example

I'm reading the Learn You a Haskell book. 我正在读“了解你一本哈斯克尔”一书。 I'm struggling to understand this applicative functor code: 我很难理解这个应用程序的编码器代码:

(*) <$> (+3) <*> (*2) $ 2

This boils down to: (3+2) * (2*2) = 20 这归结为:(3 + 2)*(2 * 2)= 20

I don't follow how. 我不遵循如何。 I can expand the above into the less elegant but more explicit for newbie comprehension version: 我可以将上面的内容扩展为不那么优雅但更明确的新手理解版本:

((fmap (*) (+3)) <*> (*2)) 2

I understand the basics of the <*> operator. 我理解<*>运算符的基础知识。 This makes perfect sense: 这很有道理:

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

But I don't see how the command works? 但我不知道命令是如何工作的? Any tips? 有小费吗?

One method to approach this types of questions is to use substitution. 处理这类问题的一种方法是使用替代。 Take the operator, in this case (<*>) or function, get its implementation and insert it to the code in question. 在这种情况下,使用运算符(<*>)或函数,获取其实现并将其插入到相关代码中。

In the case of (*) <$> (+3) <*> (*2) $ 2 you are using the ((->) a) instance of Applicative found in the Applicative module in base , you can find the instance by clicking the source link on the right and searching for "(->": 在的情况下(*) <$> (+3) <*> (*2) $ 2您所使用的((->) a)的实例Applicative中发现Applicative在基本模块 ,可以发现实例通过单击右侧的源链接并搜索“( - >”:

instance Applicative ((->) a) where
    pure = const
    (<*>) f g x = f x (g x)

Using the definition for (<*>) we can continue substituting: 使用(<*>)的定义,我们可以继续替换:

((fmap (*) (+3)) <*> (*2)) 2 == (fmap (*) (+3)) 2 ((*2) 2)
== (fmap (*) (+3)) 2 4

Ok now we need the Functor instance for ((->) a) . 好了,我们需要((->) a)的Functor实例。 You can find this by going to the haddock info for Functor , here clicking on the source link on the right and searching for "(->" to find: 您可以通过为黑线鳕信息发现这个Functor在这里点击右边的源链接,并搜索“( - >”中找到:

instance Functor ((->) r) where
    fmap = (.)

Now continuing substituting: 现在继续代替:

(fmap (*) (+3)) 2 4 == ((*) . (+3)) 2 4
== (*) ((+3) 2) 4
== (*) 5 4
== 20


A more symbolic appraoch 一个更具象征意义的appraoch

Many people report better long term sucess with these types of problems when thinking about them symbolically. 许多人在用象征性思考这些问题时会报告更好的长期成功。 Instead of feeding the 2 value through the problem lets focus instead on (*) <$> (+3) <*> (*2) and only apply the 2 at the end. 而不是通过问题提供2值,而是将焦点放在(*) <$> (+3) <*> (*2)并且仅在末尾应用2。

(*) <$> (+3) <*> (*2)
== ((*) . (+3)) <*> (*2)
== (\x -> ((*) . (+3)) x ((*2) x))
== (\x -> ((*) . (+3)) x (x * 2))
== (\x -> (*) (x + 3) (x * 2))
== (\x -> (x + 3) * (x * 2))
== (\x -> 2 * x * x + 6 * x)

Ok now plug in 2 for x 好的,现在插入2 for x

2 * 2 * 2 + 6 * 2
8 + 12
20

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM