澄清列表monad运算符的作用

时间:2014-05-30 17:11:12

标签: haskell monads pointfree

我遇到了一个Haskell函数,它告诉我们列表是否已排序,而且我无法理解它是如何工作的。

有问题的代码是

f = zipWith (<=) <*> tail

我理解为与

等同(以点式)
f' xs = zipWith (<=) xs (tail xs)

并作为示例返回

f [4, 5, 1] == [True,False]

我认为它与列表monad和顺序应用程序有关,但如果有人能让我的意思更清楚,我将不胜感激。 <*>到底在做什么?

2 个答案:

答案 0 :(得分:12)

此处的<*>不会对[a]申请人采取行动,而是在(->) a申请案例中执行。

基本上

 instance Applicative ((->) a) where
   pure = const -- same as monadic return
   f <*> a = \x -> f x (a x)

因此它就像函数应用程序一样,但也将应用程序包装在一个函数中,并将参数提供给双方。

扩展你的功能

 zipWith (<=) <*> tail
 \x -> zipWith (<=) x (tail x)
 \(x:xs) -> zipWith (<=) (x:xs) xs

一般来说,将<*>视为功能应用+一些额外的好东西是正确的。你几乎可以把它读成空格!

答案 1 :(得分:7)

<*>实际上来自(->) a作为Applicative Functor。它是一个S-combinator,它以您在扩展中指定的方式将参数(扩展中的列表xs)分配给两个函数(zipWith (<=)tail):{{1 }}

要理解这一点,您需要检查应用的(f <*> g) x = f x (g x)类型。由于它的两个参数都是(<*>),我们讨论的是a->b作为Applicative Functor而不是List。