【问题标题】:Different numbers of arguments when pattern matching Maybe模式匹配时不同数量的参数可能
【发布时间】:2015-04-27 03:46:23
【问题描述】:

我遇到了一个我不太明白的问题。我以为我可以在 Haskell 中编写这样的代码:

foo :: Maybe Int -> Int
foo Nothing = 0
foo Just x = x

但是当我尝试编译它时,我得到了错误:

'foo' 的方程有不同数量的参数

我可以通过将我的代码更改为以下内容来修复它:

foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x

这让我觉得 GHC 将 Just 解释为 foo 的参数。但是 Haskell 禁止使用大写字母来开始变量名,所以我认为这里不应该有任何歧义。怎么回事?

【问题讨论】:

  • 不完全确定,但Just 是否被视为Nothing,即作为没有任何参数的构造函数?这可以解释问题。

标签: haskell pattern-matching


【解决方案1】:

你是对的,Just 是否是构造函数并没有歧义——但构造函数可以没有参数! Haskell 的模式匹配不查找涉及的名称,它是严格的语法,foo Just x = x 是一个格式完美的函数定义子句。这是错误的类型

Prelude> let foo Just x = x

<interactive>:2:9:
    Constructor ‘Just’ should have 1 argument, but has been given none
    In the pattern: Just
    In an equation for ‘foo’: foo Just x = x

但是如果有不同的数据类型,那就没问题了:

Prelude> data Justice = Just
Prelude> let foo Just x = x
Prelude> :t foo
foo :: Justice -> t -> t
Prelude> foo Just ()
()

Just 可以是一个空构造函数(如第二个示例中所示),并且由于函数应用程序是左关联的,编译器将 Justx 解析为单独的参数,你会得到“不同数量的参数“ 错误。 (正如您在上面看到的,如果没有 Nothing 的情况,您实际上会收到该表单代码的类型错误。)

【讨论】:

    【解决方案2】:

    这个想法是模式语法应该反映应用程序语法。如果我调用foo 我不能写foo Just x,因为这意味着别的东西(如果foo(Int -&gt; Maybe Int) -&gt; Int -&gt; Int 类型,那么它甚至可以工作)。对于需要括号的位置,模式与表达式有不同的规则会很奇怪。

    在更复杂的情况下,编写不带括号的复合模式并相信编译器会自动对事物进行分组也会分崩离析。这应该是什么意思?

    foo Just x : xs = ...
    

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多