Haskell - 在模式匹配的 guard 右侧使用通配符

3

Lets say i have a piece of code like this:

test pattern
 | pattern == (_,NOT (WIRE _)) = 1     
 | pattern == (_,AND (WIRE _) (WIRE _)) = 2
 | otherwise = 0

我正在尝试将其与几种可能性之一进行匹配,其中一些只有一个(WIRE“”),而另一些则有两个。我的实际输入如下:例如:(“p”,NOT(WIRE“x”))。我希望有一个可以接受任何字母作为输入的模式(我希望使用_),但是失败了(非法_)。在Haskell中是否可能做到这一点?


字符串是一个列表。为了对一个列表进行模式匹配,你需要使用列表构造器(:)。如果你想要模式匹配一个只有一个元素的列表,可以尝试使用"x:[]"或者"_:[]"。 - jrockway
下划线(_)在同一个守卫中是否应该匹配? - LarsH
这个问题有几个令人困惑的地方,但你应该首先不使用 guards,而是使用一系列方程式,例如 test (_, NOT (WIRE _)) = 1 - Reid Barton
@LarsH 不,实际输入将使它们与p x匹配。或者如果有两根导线p x x。@Reid 谢谢!为什么它不能在guard中工作呢? - commentator8
为了进一步推动Reid的想法,使用以下代码:test2(_,NOT(WIRE _))= 1 test2(_,AND(WIRE _)(WIRE _))= 2最好的默认(否则)情况是什么,即test2 _ = 0等效。这不起作用,我想说的是任何其他输入= 0。谢谢! - commentator8
2个回答

7

编辑后,这个意思更加清晰了。

== 比较的是 ,但 _ 是一个 模式。模式出现在以下语法上下文中:

  • 作为(模式)绑定的左侧,“等号”之前的内容,在顶层或在 where 块或 let 表达式或命令(在 do 表示法中)中;
  • do 表示法或列表推导式中,位于 <- 的左侧;
  • case 表达式中,位于 -> 的左侧;
  • 作为函数的形式参数,无论是在函数绑定还是 lambda (\) 表达式中。

(我希望我没有忘记任何一个!)在您的情况下,您可以通过简单地编写来实现您想要的结果

test (_, NOT (WIRE _)) = 1
test (_, AND (WIRE _) (WIRE _)) = 2
test _ = 0

您可能会问什么是“pattern == (_, NOT (WIRE _))”的正确版本。那么,您可以写成:
case pattern of
  (_, NOT (WIRE _)) -> True
  _ -> False

谢谢,这样就清楚了一些。作为Haskell,我还需要一段时间才能完全掌握它... - commentator8
很棒的答案...既有教育性又有解决问题的作用。 :-) - LarsH
我认为也值得指出相反的情况:在模式匹配中,所有的标识符都是模式而不是值。所以NOTWIRE需要是数据构造函数或者(字符串或数字)字面值才能起作用。在这种情况下它是有效的,因为它们是大写的。学习Haskell的人经常在某个时候被这个问题绊倒。例如,你不能通过模式匹配来测试常量 - f someNum = error "not that one!"f x | x == someNum = error "not that one!" 是完全不同的。 - mokus

0

你为什么需要这个保护?我有什么遗漏吗?以下是我认为你正在寻找的合法Haskell代码。

test (_,NOT (WIRE _)) = 1     
test (_,AND (WIRE _) (WIRE _)) = 2
test _ = 0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接