【问题标题】:How to define multiple patterns in Frege?如何在 Frege 中定义多个模式?
【发布时间】:2017-02-11 08:16:47
【问题描述】:

我在Frege 中定义一个使用多种模式的函数时遇到了一些问题。基本上,我通过遍历元组列表来定义映射。我已将其简化为以下内容:

foo :: a -> [(a, b)] -> b
foo _ [] = [] --nothing found
foo bar (baz, zab):foobar
 | bar == baz = zab
 | otherwise  = foo bar foobar

我收到以下错误:

E morse.fr:3: redefinition of `foo` introduced line 2

我见过像this 这样的其他例子,它们确实在函数定义中使用了多种模式,所以我不知道我做错了什么。为什么我在这里收到错误?我是 Frege 的新手(也是 Haskell 的新手),所以我可能缺少一些简单的东西,但我真的不认为这应该是一个问题。

我正在使用 3.24-7.100 版本进行编译。

【问题讨论】:

  • 您可能需要在 (baz, zab):foobar 模式周围添加括号。类似foo bar ((baz, zab):foobar)

标签: haskell frege


【解决方案1】:

这是一个纯粹的句法问题,会影响到 Haskell 家族语言的新手。用不了多久,你就会内化函数应用优先于中缀表达式的规则。

这有后果:

  • 函数应用的复杂参数需要括号。
  • 在中缀表达式中,运算符两侧的函数应用程序不需要括号(但是,函数应用程序的各个组件可能仍需要括号)。

此外,在弗雷格中,以下规则成立:

就双方允许的词位而言,定义左侧的函数应用和中缀表达式的语法与右侧的相同。 (这仅在不使用 @~ 时在 Haskell 中成立。)

这样你就可以像这样定义一个加法函数:

data Number = Z | Succ Number

a + Z      = a
a + Succ b = Succ a + b

因此,当您将它应用到您的示例时,您会从语法上看到,您将重新定义 : 运算符。为了实现你想要的,你需要这样写:

foo bar ((baz, zab):foobar) = ....
--      ^                 ^

这对应于您将foo 应用于您正在构建的列表的情况:

foo 42 (x:xs)

当你写作时

foo 42 x:xs

这意味着

(foo 42 x):xs

【讨论】:

  • 这很有意义。谢谢你的详细解答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多