简单的应用函数示例

时间:2014-05-29 01:53:27

标签: haskell functor applicative

我正在阅读“了解你一本哈斯克尔”一书。我很难理解这个应用程序编码器代码:

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

归结为:(3 + 2)*(2 * 2)= 20

我不遵循如何做。我可以将上面的内容扩展为不那么优雅但更明确的新手理解版本:

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

我了解<*>运算符的基础知识。这很有道理:

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

但我不知道命令是如何工作的?有什么提示吗?

1 个答案:

答案 0 :(得分:20)

解决这类问题的一种方法是使用替代。在这种情况下,使用运算符(<*>)或函数,获取它的实现并将其插入到相关代码中。

如果(*) <$> (+3) <*> (*2) $ 2您使用the Applicative module in base中的((->) a) Applicative实例,则可以通过点击右侧的源链接找到该实例,正在搜索&#34;( - &gt;&#34;:

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

使用(<*>)的定义,我们可以继续替换:

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

好了,现在我们需要((->) a)的Functor实例。您可以通过转到Functor的密码锁信息找到此信息,here点击右侧的源链接并搜索&#34;( - &gt;&#34;查找:

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

现在继续代替:

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


更具象征意义的appraoch

许多人在用象征性的方式思考这些问题时,会报告更好的长期成功。不是通过问题提供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)

好了,现在插入2 for x

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