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