模式匹配Haskell高阶函数?

时间:2015-03-11 20:43:13

标签: haskell

想象一下,我有一个自定义类型和两个函数:

type MyType = Int -> Bool

f1 :: MyType -> Int
f3 :: MyType -> MyType -> MyType

我尝试按如下方式进行模式匹配:

f1 (f3 a b i) = 1

但它失败了,错误:Parse error in pattern: f1。做上述事情的正确方法是什么?基本上,我想知道有多少f3(作为a和b可能是f3或其他一些功能)。

2 个答案:

答案 0 :(得分:6)

您无法在功能上进行模式匹配。对于(几乎)任何给定的函数,有无数种方法来定义相同的函数。事实证明,在数学上,计算机始终无法确定给定的定义是否表达与另一个定义相同的功能。这也意味着Haskell无法可靠地判断函数是否与模式匹配;所以语言根本不允许。

模式必须 单个变量应用于其他模式的构造函数。记住构造函数以大写字母开头,变量以小写字母开头,模式f3 a n i无效;模式f3的“头部”是变量,但它也适用于ani。这是你得到的错误信息。

由于函数没有构造函数,因此可以匹配函数的 only 模式是单个变量;匹配所有函数(无论如何都要传递给模式的正确类型)。这就是Haskell如何强制执行“无功能模式匹配”规则。基本上,在更高阶函数中,根本没有任何关于你已经给出的函数的信息,除了以将其应用于某事并看看它的作用。

函数f1的类型为MyType -> Int。这相当于(Int -> Bool) -> Int。因此,需要类型为Int -> Bool函数参数。我希望f1的等式看起来像:

f1 f = ...

您不需要通过模式匹配来“检查”它是否是Int -> Bool函数;类型保证它将是。

你不能告诉它是哪一个;但这通常是将函数作为参数的重点(这样调用者就可以选择任何函数,因为他们知道你将以同样的方式使用它们。)

我不确定你的意思是“我想知道有多少f3在那里”。 f1始终会收到单个函数,而f3根本不是要传递给f1的正确类型的函数(它是MyType -> MyType -> MyType },而不是MyType)。

答案 1 :(得分:4)

一旦应用了一个函数,它的句法形式就会丢失。现在有办法,我应该{1}}为您提供区分2 + 3的内容。它可以来自52 + 3,或仅仅是3 + 2

如果你需要捕获句法结构,那么你需要使用句法结构。

5

此处数据类型data Exp = I Int | Plus Exp Exp justFive :: Exp justFive = I 5 twoPlusThree :: Exp twoPlusThree = I 2 `Plus` I 3 threePlusTwo :: Exp threePlusTwo = I 2 `Plus` I 3 会捕获数字表达式,我们可以对它们进行模式匹配:

Exp

但是等等,为什么我要区分"构造函数"我可以模式匹配和...." 其他语法"哪个我不能?

基本上,构造函数是惰性的。 isTwoPlusThree :: Exp -> Bool isTwoPlusThree (Plus (I 2) (I 3)) = True isTwoPlusThree _ = False 的行为是......什么也不做,只是留在一个有两个名为" Plus x y"并使用Plus _ _x表示的值插入两个广告位。

另一方面,功能应用是最惰性的!将表达式应用于函数时,函数y将使用应用值替换其正文中的(\x -> ...) es。此动态缩减行为意味着无法获得"功能应用程序"。一看到它们就会消失在空气中。