Haskell:为什么我不能模式匹配函数?

时间:2015-02-09 04:41:37

标签: haskell functional-programming

如:

extract (f x) = x

我想要做的是从函数或类型构造函数中提取参数,例如

extract succ 4 = 4
extract Just 4 = 4

PS。 extract(f x)= f也不起作用。

3 个答案:

答案 0 :(得分:6)

函数式编程中的一个关键概念,尤其是纯函数式编程,是等式推理。 Haskell中的=实际上是相等的(除了模式匹配的顺序等等)。所以当我们写

f 3 = 12

这意味着f 312实际上是同一件事 - 完全无法区分。由于extract 12没有任何意义,extract (f 3)也没有。

从另一个方向来看,在运行时,无法通过将某个函数应用于某个其他值来判断是否形成了某个值。提供此类信息通常非常昂贵,并且通常不会有用。

答案 1 :(得分:4)

"从函数中提取参数"需要反转所述函数,这只有当函数是 injective 时才有可能。更重要的是,假设

square x = x*x

root (square x) = x   -- assume it works, somehow

我们应该

root (square 2)    = 2
root (square (-2)) = -2
root 4             = ???

最后42-2的平方,并且我们无法将任何结果与其关联。 square函数不是单射的,因此它的反函数甚至不是函数。

更糟糕的是,由于4等于上述两个方格,因此参照透明度要求上述两行返回相同的结果。但情况并非如此。

答案 2 :(得分:1)

您绝对可以使用数据构造函数(例如您的示例Just)对数据结构进行模式匹配。你需要的是将它包装在括号(Just 4)中,否则你的extract函数看起来就像是采用数据构造函数而不是构造值。

在您的情况下,您需要:

extract (Just x) = x

事实上,这是fromJust函数的一部分。

另一个答案解释了为什么你不能与功能应用相匹配。对此,我将补充一点,它有点像获得反函数的神奇方法。如果有extract (f x) = x,那就像g一样神奇地g . f = id。在您的情况下,您定义了一个函数succ,我认为它是

succ x = x+1

现在,如果extract (succ x) = x是可能的,由于等式推理,extract类型为Integer -> Integer,你会神奇地构造succ的倒数,{{1 }}

尽管如上所示,可能的是与数据结构相匹配。

您可以定义一个新的数据类型,而不是处理x-1的函数succ

Integer

然后轻松拥有提取功能:

data Nat = Zero | Succ Nat

请记住,可以,并且事实上鼓励他们对extra Zero = Zero extract (Succ x) = x 之类的内容进行模式匹配。