Haskell无可辩驳的模式匹配

时间:2017-09-09 09:24:49

标签: haskell functional-programming pattern-matching

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

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

  

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

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

int func_add(int a, int d) 

然后传递一些其他类型的值如字符串将是模式匹配失败,如果我是正确的。因此,将func_add称为func_add("trs", 5)是一种模式不匹配的情况。

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

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

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:7)

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

data Color = Red | Green | Blue | Other String

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

foo :: Color -> String
foo Red = "Red"
foo Green = "Green"
foo Blue = "Blue"
foo (Other s) = s

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

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

如果我们写完:

foo :: Color -> String
foo c = "Some color"
foo Red = "Red"

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

答案 2 :(得分:2)

在Haskell中,您可以通过各种方式定义类型。其中一个是引入 sum类型,如下所示:

data FooBar = Foo Int | Bar Bool

您可以尝试使用模式匹配来编写这样的函数:

myFunction (Foo x) = x

然而,这将是一个部分匹配的函数,如果你尝试用myFunction (Bar False)调用它,你会得到一个例外。

另一方面,您也可以定义单个案例和类型,如下所示:

data MyInt = MyInt Int

在这里,您可以编写如下函数:

myFunction' (MyInt x) = x

在这里,您仍在使用模式匹配,但由于只有一个案例,因此这是一个完全匹配。如果调用代码编译,则匹配不会失败。

上面的MyInt实际上只是Int的包装器,所以你可以说如果你编写一个带Int的函数,就像这样,它就是同一种模式匹配:

myFunction'' :: Int -> Int
myFunction'' x = x + 42

虽然Int没有可用于模式匹配的值构造函数,但x是一种始终与Int值匹配的模式。因此,您可以说函数参数是始终成功的匹配。