【问题标题】:Using `++` in pattern matching在模式匹配中使用 `++`
【发布时间】:2016-07-17 07:07:57
【问题描述】:

在 GHC 解释器中输入以下内容

let describe' all@([x] ++ [y]) = "The first letter of " ++ all ++ " is " ++ [x]

产量

模式中的解析器错误:[x] ++ [y]

为什么 Haskell 无法将模式 all@([x] ++ [y])"HI"[1,2] 等表达式匹配?

【问题讨论】:

  • 基本上他不知道列表的长度是多少,++ 实际上是一个函数,所以你不能对它进行模式匹配,例如 Haskell 模式匹配构造函数。
  • 可能是因为模棱两可?
  • 所以haskell没有看到[x] + [y],它看到了++的返回值,在这种情况下是一个大小不明确的列表?
  • 不,它只会看到函数 ((++)) 并会因语法错误而停在那里 - 就像您的其他问题一样

标签: haskell pattern-matching parse-error


【解决方案1】:

假设您可以在 ++ 上进行模式匹配 - 现在考虑如何匹配:

a ++ b = [1,2]

你可以:

  • a = [1,2], b = []
  • a = [1], b = [2]
  • a = [], b = [1,2]

现在什么是正确的?


技术原因是++ 不是数据构造函数;)


在您的具体情况下,您可以使用

let describe' all@[x,y] = "The first letter of " ++ all ++ " is " ++ [x]

(只会匹配长度为完全 2的字符串)

或更好

let describe' all@(x:_) = "The first letter of " ++ all ++ " is " ++ [x]

(将匹配所有长度至少为 1 的字符串)

一个安全的版本是这样的

describe' :: String -> String
describe' ""        = "your input was empty"
describe' all@(x:_) = "The first letter of " ++ all ++ " is " ++ [x]

【讨论】:

  • 确实!如果模式匹配有那么神奇,我会尝试类似let foo (isProofOfPneqNP s) = "Eureka! " ++ s in foo True ;-))
  • 我认为这就是老鼠建造地球的目的;)
  • ... 或Curry(只是说这种结构原则上是可能的)。
【解决方案2】:

您只能在模式匹配中使用构造函数。模式[x] 与模式x:[] 脱钩,其中:[] 都是构造函数。但是,++ 是一个函数。这是 Haskell 语言设计的一个小缺陷,因为我们无法快速区分我们定义为函数的符号以及来自它们的数据类型声明的符号。如需完整处理,请参阅section 3 of the Haskell 2010 Language Report

【讨论】:

  • 虽然,中缀构造函数必须开始:,所以你至少可以确定哪些函数是不是构造函数。所以++ 绝对不是构造函数,而像:+ 这样的东西可能 是构造函数。
猜你喜欢
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 2012-09-13
  • 2012-01-12
  • 2011-08-08
  • 2012-11-25
  • 2017-11-28
相关资源
最近更新 更多