【问题标题】:Understanding the functions elem and isInfixOf了解 elem 和 isInfixOf 函数
【发布时间】:2011-12-12 13:09:44
【问题描述】:

前段时间我问了一个关于函数elemhere的问题,但我认为答案并不完全令人满意。我的问题是关于表达式:

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]

【问题讨论】:

  • 请尝试改写问题。你问elemisInfixOf之间的区别吗?从定义/文档中应该可以清楚地看到这一点。
  • @larsmans 不完全是。我知道它们是什么,但我想问的是如何使用它们以及为什么
  • 考虑改用flip elem [1, 2]
  • 谢谢,这是原始版本。正如我所说,我的问题主要涉及如何以及为什么而不是什么。现在已经解决了。

标签: haskell


【解决方案1】:

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

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

但是,当我们使用反引号来制作 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

【讨论】:

  • 那么isInfixOf的情况呢?
  • @manuzhang,对于isInfixOf,参数的顺序也相反,只需应用与答案中相同的推理即可。我考虑过在这种情况下进行编辑,但它只是复制粘贴我所说的 elem 替换为 isInfixOf
  • @HaskellElepant 谢谢我明白了。相反的方式可能是any (elem [1,2,3])[[[1,2,3],[1,2,4]],[[1,2,5]]]any (`isInfixOf` [1,2,3,4]) [[1,2,3],[1,2,3,4,5]]
  • 如果我的回答有帮助,请随时投票甚至接受答案。
  • 当然,这就是我所做的!我是 Haskell 的新手,对 lambda 函数一无所知,但仍然习惯于函数式编程。非常感谢您的帮助。
【解决方案2】:

在函数名周围使用反引号会将其变成中缀运算符。所以

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

【讨论】:

    【解决方案3】:

    它叫partial application

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

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

    【讨论】:

    • 但是any (elem [1, 2]) [[1,2],[1,2,3]] 也不会这样做
    • elem [1, 2] [[1,2],[1,2,3]] 应该进行类型检查,但正如您所说,any (elem [1, 2]) [[1,2],[1,2,3]] 没有。我认为您在这里想要的是any (elem [1, 2]) [[[1,2,3],[1,2,4]],[[1,2,5]]],正如您在另一条评论中所说的那样。所以你有一个列表列表。
    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 2011-08-22
    • 2022-07-14
    • 2021-01-12
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多