Applicative Programming with Effects介绍了交换法:
u <*> pure x = pure (\f -> f x) <*> u
为了尝试理解它,我尝试了以下示例 - 表示左侧。
ghci> Just (+10) <*> pure 5
Just 15
我怎么能用右手边写这个例子?
此外,如果u
是f (a -> b)
,其中f
是Applicative
,那么右侧的功能是什么:pure (\f -> f x) ...
?< / p>
答案 0 :(得分:5)
它将被写为
pure (\f -> f 5) <*> Just (+10)
甚至
pure ($ 5) <*> Just (+10)
在这种情况下两者都是等价的。从字面上看,你正在使用pure
包装一个函数,该函数将另一个函数作为其参数,然后将x
应用于它。您提供f
作为Just
的内容,在本例中为(+10)
。当你看到(\f -> f x)
的lambda语法时,它是非常文字的,这是一个用于这个定义的lambda。
答案 1 :(得分:2)
这个定律的关键在于Applicative
Functor保持指数:在原点中指数是什么,在类别的图像中也是指数。
请注意Applicative
Functor的实际操作是以下类型的转换:strength :: (f a, f b) -> f (a, b)
;然后ap
或<*>
只是结果的fmap eval
,或者写得完整,ap = curry $ fmap (uncurry ($)) . strength
。
然后,这项法律规定,因为在原点g $ x == ($ x) $ g
中,提升($)
,x
和($ x)
应该保持平等。请注意,“普通”Functor
仅在g
被解除时才会保留相等,但Applicative
Functors将为f (a->b)
类型的任何对象保留此相等性取代g
。这样整个类型f (a->b)
的行为类似于f a -> f b
,而对于“普通”Functor
,它只需要像f a -> f b
一样表示原点中箭头的图像(到使图表通勤并履行Functor
)的承诺。
至于代表法律的右手边,你已经被建议从字面上理解,pure ($ 5) <*> Just (+10)