Haskell无可辩驳的模式匹配

Agn*_*ngh 10 haskell functional-programming pattern-matching

为了开始进入Haskell的道路,我选择了其中一位创作者Hudak的书.所以,我正在经历对Haskell的温和介绍.

我一直试图理解以下陈述:

从技术上讲,形式参数也是模式,但它们永远不会与值相匹配.

从我对C语言(或者简称为非函数语言)的较小但相对较大的适应性,我可以形成形式参数是函数定义中的参数.所以,假设在C中有如下函数:

int func_add(int a, int d) 
Run Code Online (Sandbox Code Playgroud)

然后传递一些像字符串这样的其他类型的值将是模式匹配失败,如果我是正确的.所以呼吁func_add作为func_add("trs", 5)是模式不匹配的情况.

如果一段代码通过传递不同类型的参数来调用函数,那么在Haskell中很可能会出现错误理解或解释的可能性.

那么,为什么说在Haskell形式参数是无可辩驳的模式匹配?

Tar*_*mil 7

不,传递一些其他类型的值不是模式匹配中的失败.这是一个类型错误,代码甚至不会编译.正式参数是良好类型程序的无可辩驳模式,这是编译器允许您运行的唯一类型的程序.


Wil*_*sem 7

你描述的不是一种模式,它是一种类型.Haskell也有类型,这些在编译时解决.每次都可以有几种模式.例如,列表定义为:

data Color = Red | Green | Blue | Other String
Run Code Online (Sandbox Code Playgroud)

现在我们可以定义一个函数foo:

foo :: Color -> String
foo Red = "Red"
foo Green = "Green"
foo Blue = "Blue"
foo (Other s) = s
Run Code Online (Sandbox Code Playgroud)

粗体元素都是模式.但这些都不是无可辩驳的:第一个将检查我们是否已经给出了函数a Red,第二个是否我们已经给出了它Green,第三个是否是值Blue,最后我们有一个模式(Other s)将匹配所有Other模式(无论是什么sis)的值,因为s变量,变量是无可辩驳的模式:我们不对字符串的值执行任何检查.

请注意,这些检查是在运行时完成的:如果我们调用foo "Red",我们将在编译时获得类型错误,因为Haskell编译器知道它foo具有类型Color -> String.

如果我们写的:

foo :: Color -> String
foo c = "Some color"
foo Red = "Red"
Run Code Online (Sandbox Code Playgroud)

c是一种无可辩驳的模式:它将匹配任何Color对象,因此第二行foo Red永远不会匹配,因此c无可辩驳的模式.