【问题标题】:Haskell pattern not matched [_]Haskell 模式不匹配 [_]
【发布时间】:2017-11-13 07:00:57
【问题描述】:

我一直在尝试使以下代码工作:

{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
import Data.List
format :: String -> String
format [] = []
format (a:b:xs)
 | a == 'W' && b == 'U' = " " ++ format (drop 1 xs) 
 | otherwise = a : format (b:xs)

songDecoder :: String -> String
songDecoder xs = unwords. words . format $ xs

当我测试时:

歌曲解码器“AWUBBWUBC”

我希望“ABC”作为输出。但是,我收到了一个不寻常的模式匹配警告:

Pattern match(es) are non-exhaustive
In an equation for ‘format’: Patterns not matched: [_]

我不确定为什么我需要匹配 [_]

format (a:b:xs)

请帮忙。

【问题讨论】:

  • 如果您使用-Wall 打开警告,GHC 会在编译时对此发出警告,并指出要匹配的缺失大小写。推荐。

标签: string list haskell pattern-matching


【解决方案1】:

在模式 (a:b:xs) 中,您只匹配长度 >= 2 的列表。您缺少单项列表的模式。

例如,这些匹配(a:b:xs):

  1. "AWUBBWUBC" -- a 绑定到 "A"b 绑定到 "W"xs 绑定到 "UBBWUBC"'U':'B':'B':'W':'U':'B':'C':[] 的语法糖)。
  2. "AWU" -- ab 绑定如上,但 xs 现在绑定到 "W"
  3. "AW" -- ab 再次分别绑定到 "A""W"

"A" 之类的东西不会,因为您可以将 a 绑定到 "A"xs 到空列表,但您没有任何 b

我希望这能解释清楚!

【讨论】:

  • 谢谢埃里克。我添加了 format (a:[]) = a : [] 并且成功了!!
  • 很高兴为您提供帮助。添加了有关模式如何工作的更多详细信息。希望它们对您将来的 Haskell 编码有用!
【解决方案2】:

就像@EricFulmer 在他的回答中写道,(a:b:xs) 匹配具有两个或更多项目的列表。所以你的功能是:

format [] = ...       -- empty list
format (a:b:xs) = ... -- two or more

Haskell 警告说,带有一个元素 [_] 的列表将不匹配以下任何行:两种模式都将失败。

因此,您应该添加一个子句,以指定在列表包含一个元素的情况下应该发生什么,例如(并且可能):

format a@[_] = a

其中@ 是一个别名运算符,它与一个只有一个元素的列表绑定。

然后我们得到:

format :: String -> String
format [] = []
format a@[_] = a
format (a:b:xs)
 | a == 'W' && b == 'U' = " " ++ format (drop 1 xs) 
 | otherwise = a : format (b:xs)

我们可以通过将比较移动到模式匹配中来使函数更优雅:

format :: String -> String
format [] = []
format a@[_] = a
format ('W':'U':xs) = format $ drop 1 xs 
format (a:b:xs) = a : format (b:xs)

现在最后一种情况可以简化为:

format (a:xs) = a : format xs

现在第二个子句(我们的format a@[_])变得过时了,因为最后一个子句也处理这种情况。所以我们把函数变成:

format :: String -> String
format [] = []
format ('W':'U':xs) = format $ drop 1 xs 
format (a:xs) = a : format xs

我个人认为这更优雅,因为这里很清楚您要与第二个模式匹配的目标(您不必编写一系列条件)。此外,几乎可以从语法上看出该函数处理所有可能的输入。

【讨论】:

    猜你喜欢
    • 2021-05-22
    • 1970-01-01
    • 2017-05-08
    • 2019-03-01
    • 2016-10-29
    • 2017-10-12
    • 2011-11-30
    • 2019-05-17
    • 2012-10-04
    相关资源
    最近更新 更多