【问题标题】:Haskell - wildcard use on right side of guard in patternsHaskell - 模式中守卫右侧的通配符使用
【发布时间】:2011-04-17 14:14:51
【问题描述】:

假设我有一段这样的代码:

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

我试图将它与几种可能性之一进行匹配,一些与一种(WIRE“”),一些与两种。我有如下实际输入,例如:(“p”,NOT(WIRE“x”))。我想要一个可以接受任何字母作为输入的模式(我希望使用 _)并且失败得很惨(非法 _)。有可能在haskell中做到这一点吗?

【问题讨论】:

  • 字符串是一个列表。要对列表进行模式匹配,请使用列表构造函数 (:)。如果要对单元素列表进行模式匹配,请尝试“x:[]”或“_:[]”
  • _是否应该相互匹配(在同一个警卫内)?
  • 关于这个问题有几个令人困惑的地方,但你应该从根本不使用守卫开始,而只是像test (_, NOT (WIRE _)) = 1 这样的一系列方程。
  • @LarsH 不,他们提供的真实输入将使它们与 p x 匹配。或者如果有两条线 p x x 说。 @里德谢谢!为什么它是这样工作的,而不是在守卫内?
  • 为了进一步 Reid 的想法,使用这个: test2 (,NOT (WIRE _)) = 1 test2 (,AND (WIRE _)(WIRE _)) = 2 what是最好的默认(否则)情况,即 test2 _ = 0 等效。这不起作用,我想说的是任何其他输入 = 0。谢谢!

标签: haskell pattern-matching guard


【解决方案1】:

好的,这在编辑后更有意义。

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

  • 在(模式)绑定的左侧,即“= 之前的内容”,在顶层或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还有一段时间,直到我完全适应它......
  • 很好的答案......教育和解决方案。 :-)
  • 我认为反过来也值得指出:在模式匹配中,所有的标识符都是模式而不是值。所以NOTWIRE 需要是数据构造函数或(字符串或数字)文字才能工作。在这种情况下,它可以工作,因为它们是大写的。学习 Haskell 的人经常会在某些时候绊倒。例如,您不能通过模式匹配来测试常量 - f someNum = error "not that one!"f x | x == someNum = error "not that one!" 完全不同。
【解决方案2】:

你为什么需要警卫?我错过了什么吗?以下是我认为您正在寻找的合法 Haskell 代码。

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

【讨论】:

    猜你喜欢
    • 2019-03-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2017-07-26
    • 1970-01-01
    相关资源
    最近更新 更多