【问题标题】:Pattern match(es) are non-exaustive -- How come my "otherwise" in the final guard fails to deal with an empty list?模式匹配不是详尽无遗的——为什么我在最后一个守卫中的“否则”无法处理一个空列表?
【发布时间】:2016-12-30 02:31:07
【问题描述】:

所以我试图匹配这个模式。 MessageType 是我创建的一种类型。此函数接收一个字符串,然后根据该字符串的第一个字符,它输出一个 MessageType。每当我编译时,我都会收到一条警告:

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

这是我的代码:

parseMessage :: String -> MessageType
parseMessage (x:_)
  | x == 'I'      = Info
  | x == 'W'      = Warning
  | otherwise     = Error 1

为什么我的模式匹配并不详尽? otherwise 守卫不会抓到别的东西吗?我看不到我的函数如何无法捕获所有字符串。

当我这样编写函数时,我没有收到警告。

parseMessage []     = error "Empty String"
parseMessage (x:_) = if x == 'I'
                        then Info
                        else if x == 'W'
                        then Warning
                        else Error 1

我以这种方式重写了我的函数,因为我看到警告说“模式不匹配:[]”,所以我明确地处理了它。但是为什么在我的函数的第一个版本中,它说模式没有被处理。 otherwise怎么除了前两个守卫什么都抓不到?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    守卫特定于函数定义中的单个模式案例,所以当你写这个时:

    parseMessage (x:_)
      | x == 'I'      = Info
      | x == 'W'      = Warning
      | otherwise     = Error 1
    

    ...如果您运行parseMessage "",甚至不会咨询您的守卫。 (x:_) 模式会失败,所以它的所有守卫都会被忽略。为了使x 被绑定在保护条件内,必须是这种情况。

    要解决这个问题,您只需要添加一个处理空字符串的案例:

    parseMessage :: String -> MessageType
    parseMessage ""   = Error 1
    parseMessage (x:_)
      | x == 'I'      = Info
      | x == 'W'      = Warning
      | otherwise     = Error 1
    

    现在您已经处理了所有可能的情况。

    【讨论】:

    • 我会去掉otherwise 子句,并在末尾添加parseMessage _ = Error 1
    • 啊,我明白了。由于我设置了用于检查列表第一个元素的初始模式,因此守卫不会捕获空字符串。
    【解决方案2】:

    为什么不直接写...

    parseMessage ('I':_) = Info
    parseMessage ('W':_) = Warning
    parseMessage _       = Error 1
    

    【讨论】:

      猜你喜欢
      • 2011-10-29
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-01
      相关资源
      最近更新 更多