Haskell模式匹配

gdr*_*les 1 haskell

我有这个代码:

type Variable = String 
data Expr = T | Var Variable | And Expr Expr | Not Expr
Run Code Online (Sandbox Code Playgroud)

测试用例如下:

prop_v1 = v (Not (And (Var "y") T)) === ["y"]
Run Code Online (Sandbox Code Playgroud)

是什么意思data Expr- 它只是定义了可以输入的类型及其参数吗?即,Var需要一个Variable,And需要两个Expr.

pig*_*ker 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
Run Code Online (Sandbox Code Playgroud)

你可以看到T,Var,AndNot这头向上每个data条款都构造,并住在价值语言; 每个子句中的其余部分都以类型语言存在,说明每个组件Expr必须具有的类型.每个相应的模式由应用于模式变量的构造函数组成,这些变量代表具有给定类型的组件.基本上,函数左侧显示的模式是通过重复地将模式变量细化为其值可能采用的模式来实现的,如其类型所示.

通过模式匹配写一个函数不在于说什么的做的:它由话说输出什么对的什么输入的可能的情况.您需要将输入分析到可以轻松说出输出必须是什么的情况.那么,从一个一般情况开始......

v :: Expr -> [Variable]
v e = undefined
Run Code Online (Sandbox Code Playgroud)

......并完善它.问"你能说出它到底是什么吗?".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
Run Code Online (Sandbox Code Playgroud)

现在,在每种情况下,你能说出输出是什么吗?方便的是你可以在组件上使用递归调用.假设你已经知道什么是什么vars e1,什么vars e2时候你想说什么v (And e1 e2)一定是什么.如果你正确的步骤,程序将是正确的.

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

v (Not (And (Var "y") T))
Run Code Online (Sandbox Code Playgroud)

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

Not e1   -- with e1 = And (Var "y") T
Run Code Online (Sandbox Code Playgroud)

什么是

v e1
Run Code Online (Sandbox Code Playgroud)

?看着它,最好是

["y"]
Run Code Online (Sandbox Code Playgroud)

在这个例子中,什么是v (Not e1)在以下方面v e1?同样的.这可能表明适当的表达,以取代undefined

v (Not e1) = undefined  -- can you tell what this is now?
Run Code Online (Sandbox Code Playgroud)

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

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

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


Tik*_*vis 5

data Expr定义一个新的数据类型,指定"构造函数" Var,它采用一个VariableAnd两个表达式.

您可以Expr使用这些构造函数匹配:

fn (Var name)      = ...
fn (And exp1 exp2) = ...
...
Run Code Online (Sandbox Code Playgroud)

请注意,data Expr = ...只定义一种类型Expr.Var,And...等都是构造Expr,所以像值Var "blarg"将是类型Expr.

您可能应该阅读" 了解你一个Haskell"的前几章来学习基础知识.