为了在 haskell 的道路上抢先一步,我选择了它的创作者之一胡达克的这本书。所以,我正在经历对 haskell 的温和介绍。
我在试图理解下面的陈述时愣住了:
从技术上讲,形式参数也是模式,但它们永远不会与值不匹配。
根据我对C语言(或者广义地说,非函数式语言)的习惯,我可以认为形式参数是函数定义中的参数。因此,假设C中有一个函数,如下所示:
int func_add(int a, int d)
那么如果我是正确的,那么传递一个其他类型的值,比如string,将导致模式匹配失败,所以将func_add
调用为func_add("trs", 5)
就是模式不匹配的情况。
当一段代码通过传递不同类型的参数来调用一个函数时,这种类似的情况在Haskell中也很可能发生,但很可能会出现错误的理解或解释。
那么,为什么说在Haskell中形式参数是不可反驳的模式匹配呢?
3条答案
按热度按时间dbf7pr2w1#
你所描述的不是一个模式,它是一个类型。Haskell也有类型,并且这些类型在 * 编译 * 时解析。每个类型可以有几个模式。例如,列表定义为:
现在我们可以定义一个函数
foo
:粗体字的元素都是 * 模式 *。但这些并非不可反驳:第一个将检查我们是否已经给了函数
Red
,第二个检查我们是否已经给了它Green
,第三个检查值是否是Blue
,最后我们有一个模式(Other s)
,它将与所有Other
模式匹配(不管s
的值是什么),因为s
是一个 * 变量 *,而变量是一个不可反驳的模式:我们不对字符串的值执行任何检查。请注意,这些检查是在 * 运行时 * 进行的:然而,如果我们调用
foo "Red"
,我们将在 * 编译时 * 得到一个类型错误,因为Haskell编译器知道foo
具有类型Color -> String
。如果我们会写:
c
是一个无可辩驳的模式:它将匹配任何Color
对象,因此第二行foo Red
永远不会匹配,因此c
是一个 * 不可反驳的模式 *。dwthyt8l2#
不,传递一个其他类型的值并不是模式匹配的失败。这是一个类型错误,代码甚至无法编译。形式参数是不可反驳的模式 * 对于一个类型良好的程序 *,这是编译器允许你运行的唯一类型的程序。
aiqt4smr3#
在Haskell中,你可以用不同的方式定义类型,其中之一就是引入一个 sum type,如下所示:
您可以尝试使用模式匹配编写如下函数:
然而,这将是一个部分匹配的函数,如果你试图用
myFunction (Bar False)
调用它,你会得到一个异常。另一方面,您也可以定义单一案例总和类型,如下所示:
在这里,您可以编写如下函数:
在这里,您仍然使用模式匹配,但是由于只有一个case,所以这是一个完全匹配。如果调用代码编译,匹配不会失败。
上面的
MyInt
实际上只是Int
的一个 Package 器,所以你可以说,如果你写一个接受Int
的函数,就像这样,它是同一种模式匹配:虽然
Int
没有一个值构造函数可以用来进行模式匹配,但是x
是一个总是匹配Int
值的模式,因此可以说函数参数是一个总是成功的匹配。