作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
今天我度过了几个小时的乐趣,试图了解箭头运算符应用程序在 Haskell 中的作用。我现在正在尝试验证我的理解是否正确。简而言之,我发现对于箭头运算符适用
(f <*> g <*> h <*> v) z = f z (g z) (h z) (v z)
在继续之前,我知道 this discussion但发现它非常复杂,比我今天希望得到的要复杂得多。
为了理解 applicative 的作用,我从基础中箭头 applicative 的定义开始
instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)
然后继续探索表达式是什么
(f <*> g <*> h) z
和
(f <*> g <*> h <*> v) z
展开时的产量。
从定义我们可以看出
f <*> g = \x -> f x (g x)
因为(<*>)
是左结合的,因此如下
f <*> g <*> h = (f <*> g) <*> h
= (\x -> f x (g x)) <*> h
= \y -> (\x -> f x (g x)) y (h y)
因此
(f <*> g <*> h) z = (\y -> (\x -> f x (g x)) y (h y)) z
= (\x -> f x (g x)) z (h z)
= (f z (g z)) (h z)
= f z (g z) (h z)
最后一步是由于函数应用程序是左关联的。同样
(f <*> g <*> h <*> v) z = f z (g z) (h z) (v z)
对我来说,这为箭头应用程序的作用提供了非常清晰直观的想法。 但这正确吗?
要测试我运行的结果,例如以下内容,
λ> ((\z g h v -> [z, g, h, v]) <*> (1+) <*> (2+) <*> (3+)) 4
[4,5,6,7]
与上面得出的结果一致。
在进行上述扩展之前,我发现这个应用程序非常难以理解,因为柯里化(Currying)的使用可能会导致极其复杂的行为。特别是,在
(f <*> g <*> h <*> v) z = f z (g z) (h z) (v z)
函数可以返回其他函数。这是一个例子:
λ> ((\z g -> g) <*> pure (++) <*> pure "foo" <*> pure "bar") undefined
"foobar"
在本例中z=undefined
被所有函数忽略,因为 pure x z = x
第一个函数忽略 z
通过 build 。此外,第一个函数仅接受两个参数,但返回一个接受两个参数的函数。
最佳答案
是的,您的计算是正确的。
关于haskell - 箭头运算符应用的直观想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46992307/
我是一名优秀的程序员,十分优秀!