Haskell模式匹配

时间:2012-02-21 09:16:06

标签: haskell

我有这段代码:

type Variable = String 
data Expr = T | Var Variable | And Expr Expr | Not Expr

测试用例如下:

prop_v1 = v (Not (And (Var "y") T)) === ["y"]

data Expr的含义是什么 - 它只是定义了可以输入的类型及其参数吗?即Var需要VariableAnd需要两个Expr

3 个答案:

答案 0 :(得分:10)

Expr的数据类型声明系统地产生了一组模式,这些模式涵盖Expr类型的值 的所有可能事物。我们来做翻译

data Expr           -- any e :: Expr must be one of
  = T               -- T
  | Var Variable    -- (Var x)         -- where x :: Variable
  | And Expr Expr   -- (And e1 e2)     -- where e1 :: Expr, e2 :: Expr
  | Not Expr        -- (Not e1)        -- where e1 :: Expr

您可以看到,每个T子句的VarAndNotdata都是构造函数 ,生活在价值语言中;每个子句中的其余部分都使用类型语言,说明Expr的每个组件必须具有的类型。每个相应的模式由应用于模式变量的构造函数组成,代表具有给定类型的组件。基本上,函数左侧显示的模式是通过重复地将模式变量细化到它们的值可能采用的模式,,如其类型所示。

通过模式匹配编写函数不包括说做什么:它包括说输出是什么输入的可能情况>是。您需要将输入分析到可以轻松说出输出必须是什么的情况。所以,从一个一般情况开始......

v :: Expr -> [Variable]
v e = undefined

......并完善它。问“你能说出它到底是什么吗?”。我们无法在不了解v e的情况下了解e是什么。所以我们最好拆分 e。我们知道e :: Expr,所以我们知道它的值可以匹配的模式。制作程序行的四个副本,并在每个程序行中将e替换为上面列出的四种可能模式之一。

v :: Expr -> [Variable]
v T           = undefined
v (Var x)     = undefined
v (And e1 e2) = undefined
v (Not e1)    = undefined

现在,在每种情况下,你能说出输出是什么吗?方便的是你可以在组件上使用递归调用。假设您在尝试说明vars e1必须是什么时,您已经知道vars e2v (And e1 e2)是什么。如果你正确的步骤,程序将是正确的。

我发现从具体的例子来考虑通常是有帮助的。以你的测试为例。

v (Not (And (Var "y") T))

那应该是["y"],对吧?它匹配哪种模式?

Not e1   -- with e1 = And (Var "y") T

什么

v e1

?看着它,最好是

["y"]

在此示例中,v (Not e1)的{​​{1}}是什么?同样的。这可能会建议一个合适的表达式来替换

中的v e1
undefined

(当然,一个暗示性的例子只是一个好的开始,而不是正确性的保证。)

外卖消息:(1)通过分割模式变量来构建模式,通过查看类型的声明来确定可能的模式; (2)假设对组件的递归调用给出了正确的答案,然后尝试为整个问题构建正确的答案。

无耻的插件:shplit是我为学生构建的一个简单工具,可以机械地捕获消息(1)。

答案 1 :(得分:5)

data Expr定义了一种新的数据类型,指定了Var之类的“构造函数”,其中VariableAnd采用两个表达式。

您可以使用以下构造函数与Expr进行匹配:

fn (Var name)      = ...
fn (And exp1 exp2) = ...
...

请注意,data Expr = ...仅定义一个类型ExprVarAnd ...等都是Expr构造函数,因此Var "blarg"之类的值将属于Expr类型

你应该阅读Learn You a Haskell的前几章来学习基础知识。

答案 2 :(得分:2)

  

另外,我如何用模式定义这个函数   匹配?

对不起,这是错误的问题。 这就像有人问“我如何通过数组索引处理矩阵乘法?” (对于哪一个人可以简单回复:为什么,你怎么做没有数组索引?)

你应该问“给定一个Expr,我怎样才能找到它中出现的所有变量?”然后,模式匹配的含义会自动展开。

您的数据类型Expr是相当简单的布尔表达式的一种可能表示。你有变量,一个字面值T(代表true也许 - 顺便说一句,你确定你没有忘记F吗?)并且如果 x 是一个表达式然后是Not x ,如果 x y 是表达式,那么{{ 1}} xy

所以,首先,请准确描述(不仅仅是:“我从左到右依次写下我找到的每个变量名称。”)如何在母语中找到这样一个表达式中的所有变量。例如:“如果表达式为And,则该表达式中出现的变量列表为空。”务必涵盖所有可能的情况。然后回来,我们将向您展示如何将其转换为Haskell,但我相信到那时您会注意到它。