[英]constructor pattern matching haskell
I have this data type 我有这个数据类型
data Struct val = Empty | Exec1 val
| Exec2 val
And two dummy functions 和两个虚拟功能
apply :: Struct -> String
apply (Empty) = "matched Empty"
apply (exec struct) = "matched Exec1 or Exec2"
apply' :: Struct val -> String
apply' (Empty) = "matched Empty"
apply' (Exec1 _) = "matched Exec1"
apply' (Exec2 _) = "matched Exec2"
Second one is working fine, but the first one is causing error: "Parse error in pattern: exec". 第二个工作正常,但第一个导致错误:“在模式中解析错误:exec”。 Can you plase explain why can't I match on constructor this way: apply (exec struct) = ... ?
您能否解释一下为什么我不能以这种方式在构造函数上进行匹配:apply(exec struct)= ...?
It's causing a lot of boilerplate code when I have multiple constructors in my datatype and must pattern match them all separately. 当我的数据类型中有多个构造函数并且必须分别对它们进行模式匹配时,这会导致很多样板代码。
In general, if you have several constructors that share data, then it's usually better to refactor the data declaration to something like 通常,如果您有多个共享数据的构造函数,那么通常最好将数据声明重构为类似
data Struct val = Empty | NonEmpty StructType val
data StructType = Exec1 | Exec2
Now you can pattern match in apply
like this 现在您可以像这样在模式匹配中
apply
apply :: Struct -> String
apply (Empty) = "matched Empty"
apply (NonEmpty exec struct) = "matched Exec1 or Exec2"
and you can still also pattern match to a specific Exec-type 而且您仍然可以将模式匹配到特定的Exec类型
apply' :: Struct val -> String
apply' (Empty) = "matched Empty"
apply' (NonEmpty Exec1 _) = "matched Exec1"
apply' (NonEmpty Exec2 _) = "matched Exec2"
"exec" is not a type constructor and you can only use those in pattern matching. “ exec”不是类型构造函数,您只能在模式匹配中使用它们。
What you can do is 你能做的是
data Struct val = Empty | Exec Int val
apply :: Struct -> String
apply (Empty) = "matched Empty"
apply (Exec _ _) = "matched Exec1 or Exec2"
apply' :: Struct val -> String
apply' (Empty) = "matched Empty"
apply' (Exec 1 _) = "matched Exec1"
apply' (Exec 2 _) = "matched Exec2"
Why? 为什么? Because you can only match constructors, and
exec
is kind of a new variable. 因为您只能匹配构造函数,所以
exec
是一个新变量。 One reason for this is for example the following: 造成这种情况的原因之一如下:
data Struct2 = Empty | Exec1 String
| Exec2 Int
apply :: Struct2 -> String
apply Empty = "matched Empty"
apply (exec struct) = ??
How should anyone know which of Exec1
and Exec2
you are matching? 谁能知道您要匹配的
Exec1
和Exec2
? You couldn't apply functions here, since the actual type of struct
couldn't be determined. 您无法在此处应用函数,因为无法确定
struct
的实际类型。
If you want to reduce the pattern matching, there are a number of ways, from using case
, over different data
implementation (like @Karolis suggested) and helper functions to higher level constructs with more complex types. 如果要减少模式匹配,可以使用多种方法,从使用
case
到不同的data
实现(如建议的@Karolis)和helper函数,再到具有更复杂类型的更高级别的构造。 But that's an endless topic. 但这是一个无休止的话题。
In your particular case you can do the following: 在您的特定情况下,您可以执行以下操作:
apply :: Struct -> String
apply Empty = "matched Empty"
apply _ = "matched Exec1 or Exec2"
This will not scale nicely to more complicated results though. 但是,这将无法很好地扩展到更复杂的结果。
apply Empty = "matched empty"
apply (Exec1 _) = notEmpty
apply (Exec2 _) = notEmpty
notEmpty = "matched Exec1 or Exec2"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.