理解函数elem和isInfixOf

时间:2011-10-21 12:12:24

标签: haskell

前段时间我曾询问有关函数elem here的问题,但我认为答案并不完全令人满意。我的问题是关于表达式:

any (`elem` [1, 2]) [1, 2, 3]

我们知道elem处于反引号中,因此elem是中缀,我的解释是:

1 `elem` [1, 2] -- True
2 `elem` [1, 2] -- True
3 `elem` [1, 2] -- False

最后它会返回True,因为它是any而不是all。这看起来不错,直到我看到isInfixOf的相似表达式:

any (isInfixOf [1, 2, 3]) [[1, 2, 3, 4], [1, 2]]

在这种情况下,一个看似合理的解释似乎是:

isInfixOf [1, 2, 3] [1, 2, 3, 4] -- True
isInfixOf [1, 2, 3] [1, 2]       -- False

我想知道为什么自从

以来它们以不同的方式被使用
any (elem [1, 2]) [1, 2, 3]

会出错,

也会出错
any (`isInfixOf` [[1, 2, 3, 4], [1, 2]]) [1, 2, 3]

3 个答案:

答案 0 :(得分:6)

你的问题在于(** a)句法糖。问题是(elem b)只是elem的部分应用,即:

(elem b) == (\xs -> elem b xs)

但是当我们使用back ticks来制作elem中缀时,我们会为中缀运算符获得一个特殊的语法,其工作原理如下:

(+ a) == (\ b -> b + a)
(a +) == (\ b -> a + b)

因此,

(`elem` xs) == (\a -> a `elem` xs) == (\ a -> elem a xs)

,而

(elem xs) == (\a -> elem xs a)

所以在后一种情况下,你的参数的顺序是错误的,这就是你的代码中发生的事情。

请注意,(** a)语法糖适用于除-之外的所有中缀运算符,因为它也是前缀运算符。该规则的例外情况将在herehere进行讨论。

答案 1 :(得分:3)

在函数名称周围使用反向标记将其转换为中缀运算符。所以

x `fun` y

相同
fun x y

Haskell也有操作符部分,f.e。 (+ 1)表示\x -> x + 1

所以

(`elem` xs)

相同
\x -> x `elem` xs

\x -> elem x xs

flip elem xs

答案 2 :(得分:0)

它被称为partial application

isInfixOf [1, 2, 3]返回一个需要一个参数的函数。

any (elem [1, 2]) [1, 2, 3]是一个错误,因为您正在寻找一个元素[1, 2],并且该列表只包含数字,因此haskell无法匹配这些类型。

相关问题