【问题标题】:Haskell head/tail vs pattern matchingHaskell 头/尾与模式匹配
【发布时间】:2016-02-17 19:08:32
【问题描述】:

这里有两段代码。

工作:

joins :: [String] -> String -> String
joins [] _ = ""
joins [x] _ = x
joins xs d = head xs ++ d ++ (joins (tail xs) d)

不工作:

joins :: [String] -> String -> String
joins [] _ = ""
joins [x] _ = x
joins [x:xs] d = x ++ d ++ (joins xs d)

后者的错误日志是:

test.hs:4:18:
Couldn't match expected type `[Char]' with actual type `Char'
In the first argument of `(++)', namely `x'
In the expression: x ++ d ++ (joins xs d)
In an equation for `joins':
    joins [x : xs] d = x ++ d ++ (joins xs d)

test.hs:4:35:
Couldn't match type `Char' with `[Char]'
Expected type: [String]
  Actual type: [Char]
In the first argument of `joins', namely `xs'
In the second argument of `(++)', namely `(joins xs d)'
In the second argument of `(++)', namely `d ++ (joins xs d)'

我在这里错过了什么?

【问题讨论】:

  • 注意Data.List为此提供了intercalate函数。
  • 以上代码仅供学习,但在实际项目中我会使用您建议的功能。

标签: haskell


【解决方案1】:

使用括号,而不是方括号:

   -- vvvvvv
joins (x:xs) d = x ++ d ++ (joins xs d)

模式[x:xs]只匹配长度为1的列表,其单个元素是一个非空列表x:xs

由于您的是字符串列表,[x:xs]["banana"](其中 x='b', xs="anana")匹配,与 ["a"]x='a', xs="")匹配,但与 ["banana", "split"] 不匹配,也不与 [""] 匹配。

这显然不是你想要的,所以使用简单的括号。

(顺便说一句,... ++ (joins xs d) 中的括号是不需要的:函数应用程序绑定的比 Haskell 中的任何二元运算符都多。)

【讨论】:

  • 如果它能让你感觉好些,这至少是我本月看到的第二个问题,[x:xs] 而不是(x:xs)...
  • @MathematicalOrchid 确实,这是一个常见的错误。我还看到f [x] = ... 其中x 被假定与输入列表匹配很多次。我一直想知道这些错误扩散的原因是什么。
猜你喜欢
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 2021-05-22
  • 1970-01-01
  • 2017-05-08
  • 2019-03-01
  • 2016-10-29
相关资源
最近更新 更多