模式匹配时不同数量的参数可能

Wil*_*kel 4 haskell pattern-matching

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

foo :: Maybe Int -> Int
foo Nothing = 0
foo Just x = x
Run Code Online (Sandbox Code Playgroud)

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

'foo'的等式具有不同数量的参数

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

foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x
Run Code Online (Sandbox Code Playgroud)

这让我觉得GHC正在解释Just为一个论据foo.但是Haskell禁止使用大写字母来启动变量名,所以我不认为这里应该有任何歧义.这是怎么回事?

Ant*_*sky 11

你是对的,对于是否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
Run Code Online (Sandbox Code Playgroud)

但是对于不同的数据类型,它会很好:

Prelude> data Justice = Just
Prelude> let foo Just x = x
Prelude> :t foo
foo :: Justice -> t -> t
Prelude> foo Just ()
()
Run Code Online (Sandbox Code Playgroud)

Just可能是一个无效的构造函数(如第二个示例中所示),并且由于函数应用程序是左关联的,因此编译器会解析Justx作为单独的参数,并且您会得到"不同数量的参数"错误.(正如您在上面所看到的,如果不是这种Nothing情况,您实际上会得到该表单代码的类型错误.)