Haskell模式匹配

Haskell模式匹配,haskell,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接受一个变量,和接受两个Expr。数据Expr定义了一个新的数据类型,指定“构造函数”,比如Var接受一个变量或和接受

我有以下代码:

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
接受一个
变量
接受两个
Expr

数据Expr
定义了一个新的数据类型,指定“构造函数”,比如
Var
接受一个
变量
接受两个表达式

您可以使用以下构造函数匹配
Expr

fn (Var name)      = ...
fn (And exp1 exp2) = ...
...
请注意,
dataexpr=…
只定义了一种类型,
Expr
Var
等都是
Expr
的构造函数,因此像
Var“blarg”
这样的值将属于
Expr
类型


您可能应该阅读的前几章来学习基础知识。

dataexpr
定义了一种新的数据类型,指定了“构造函数”,如
Var
,它接受一个
变量
接受两个表达式

您可以使用以下构造函数匹配
Expr

fn (Var name)      = ...
fn (And exp1 exp2) = ...
...
请注意,
dataexpr=…
只定义了一种类型,
Expr
Var
等都是
Expr
的构造函数,因此像
Var“blarg”
这样的值将属于
Expr
类型

您可能应该阅读本手册的前几章来学习基础知识

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

对不起,这是个错误的问题。 这就像有人在问“我将如何使用数组索引实现矩阵乘法?”(对于这个问题,人们可以简单地回答:为什么,没有数组索引,如何实现它?)

你应该问“给定一个表达式,我如何才能找到其中出现的所有变量?”然后,模式匹配的含义自动展开

您的数据类型
Expr
是相当简单的布尔表达式的一种可能表示形式。你有变量,一个文本值
T
(代表
true
maybe-btw,你确定你没有忘记
F
?),如果x是一个表达式,那么x将是
而不是
x,如果x和y是表达式,那么
xy也是

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

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

对不起,这是个错误的问题。 这就像有人在问“我将如何使用数组索引实现矩阵乘法?”(对于这个问题,人们可以简单地回答:为什么,没有数组索引,如何实现它?)

你应该问“给定一个表达式,我如何才能找到其中出现的所有变量?”然后,模式匹配的含义自动展开

您的数据类型
Expr
是相当简单的布尔表达式的一种可能表示形式。你有变量,一个文本值
T
(代表
true
maybe-btw,你确定你没有忘记
F
?),如果x是一个表达式,那么x将是
而不是
x,如果x和y是表达式,那么
xy也是


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

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
Var
Not
都是构造函数,并且使用值语言;每个子句中的其余部分使用类型语言,表示
Expr
的每个组件必须具有的类型。每个对应的模式由应用于模式变量的构造函数组成代表具有给定类型的组件。基本上,显示在函数左侧的模式是通过重复地将模式变量细化为其值可能采用的模式(如其类型所示)而形成的

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

v :: Expr -> [Variable]
v e = undefined
…并改进它。问“你能告诉我它是什么吗?”。如果不进一步了解
e
,我们就无法说出
ve
是什么。所以我们最好分开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
Not e1   -- with e1 = And (Var "y") T
v e1
["y"]
v (Not e1) = undefined  -- can you tell what this is now?