为了开始进入Haskell的道路,我选择了其中一位创作者Hudak的书。所以,我正在经历对Haskell的温和介绍。
我一直试图理解以下陈述:
从技术上讲,形式参数也是模式,但它们永远不会与值匹配。
从我对C语言(或者简称为非函数语言)的较小但相对较大的适应性,我可以形成形式参数是函数定义中的参数。所以,假设C中有如下函数:
int func_add(int a, int d)
然后传递一些其他类型的值如字符串将是模式匹配失败,如果我是正确的。因此,将func_add
称为func_add("trs", 5)
是一种模式不匹配的情况。
如果一段代码通过传递不同类型的参数来调用函数,那么在Haskell中很可能会出现错误的理解或解释。
那么,为什么说在Haskell中形式参数是无可辩驳的模式匹配?答案 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
值匹配的模式。因此,您可以说函数参数是始终成功的匹配。