【问题标题】:Using cons with tail of tail in a list throws an error在列表中使用带有尾尾的 cons 会引发错误
【发布时间】:2020-12-03 00:28:14
【问题描述】:

我是 Haskell 初学者,我基本上是想了解为什么会失败:

Prelude> test
[2,3,4,1]
Prelude> tail $ tail test
[4,1]
Prelude> 2 : [4,1]
[2,4,1]
Prelude> 2 : tail $ tail test

<interactive>:27:1: error:
    • Couldn't match expected type ‘[Integer] -> t’
                  with actual type ‘[Integer]’
    • The first argument of ($) takes one argument,
      but its type ‘[Integer]’ has none
      In the expression: 2 : tail $ tail test
      In an equation for ‘it’: it = 2 : tail $ tail test
    • Relevant bindings include it :: t (bound at <interactive>:27:1)

<interactive>:27:5: error:
    • Couldn't match expected type ‘[Integer]’
                  with actual type ‘[a0] -> [a0]’
    • Probable cause: ‘tail’ is applied to too few arguments
      In the second argument of ‘(:)’, namely ‘tail’
      In the expression: 2 : tail
      In the expression: 2 : tail $ tail test
Prelude>

我看到错误消息“可能的原因:‘tail’ is applied to too little arguments”,但我不明白是什么原因造成的,因为同样的表达式也有效。

【问题讨论】:

  • 2 : tail $ tail test 等价于(2 : tail) (tail test),而不是2 : (tail (tail test))
  • @WillemVanOnsem:成功了!谢谢你。正如我在另一个答案中提到的,我确实尝试了2 : $ tail $ tail test,它返回了parse error on input ‘$’。你知道这是为什么吗?

标签: haskell cons


【解决方案1】:

您需要注意运算符分组/优先级:2 : tail $ tail test 与“将值 2 转换为 tail $ tail test”不同,5 * 3 + 2 与“将 3 + 2 的结果乘以 5”不同”。在这两种情况下,如果这是您想要的操作,您都需要添加括号。

【讨论】:

  • 啊!所以我实际上尝试过:2 : $ tail $ tail test,但也失败了。我的理解是 $ 和括号是等价的?
  • 加括号确实有效!谢谢你的回复。如果您还可以解释为什么$ din 工作,那就太棒了!
  • $ 不等同于括号,而是一种避免括号的方法,因为$ 的优先级低于(几乎)任何其他运算符。
  • @Yathi 2 : $ tail $ tail test 不起作用的原因与 5 * + 3 + 2 不起作用的原因完全相同。
  • @Yathi,但 (2:) $ tail $ tail test(:) 2 $ tail $ tail test 都可以。 (:) 是对应于 : 运算符的实际函数,(2 :)(:) 2\x -&gt; 2 : x(我不记得是哪个,而且它很少重要)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多