Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Haskell模式不匹配[\uu1]_String_List_Haskell_Pattern Matching - Fatal编程技术网

String Haskell模式不匹配[\uu1]

String Haskell模式不匹配[\uu1],string,list,haskell,pattern-matching,String,List,Haskell,Pattern Matching,我一直在努力使以下代码正常工作: {-# 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 :

我一直在努力使以下代码正常工作:

{-# 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
当我测试时:

歌曲解码器“awubc”

我期望“ABC”作为输出。然而,我得到了一个不寻常的模式匹配警告:

Pattern match(es) are non-exhaustive
In an equation for ‘format’: Patterns not matched: [_]
我不知道为什么我需要匹配,当我有

format (a:b:xs)
请帮助。

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

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

  • “awubbwbc”
    -
    a
    绑定到
    “a”
    b
    绑定到
    “W”
    xs
    绑定到
    “ubbwbc”
    'U':'b':'W':'U':'b':'C':[]
  • “AWU”
    --
    a
    b
    如上所述绑定,但是
    xs
    现在绑定到
    “W”
  • “AW”
    -
    a
    b
    再次分别绑定到
    “a”
    “W”
  • “A”
    这样的东西不会,因为您可以将
    A
    绑定到
    “A”
    并将
    xs
    绑定到空列表,但是您没有
    b
    的任何内容

    我希望这能解释它

    就像他在回答中写道的那样,
    (a:b:xs)
    将列表与两个或多个项目进行匹配。因此,您的功能如下:

    format [] = ...       -- empty list
    format (a:b:xs) = ... -- two or more
    
    Haskell警告说,只有一个元素的列表将与这些行中的任何一行都不匹配:两种模式都将失败

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

    其中,
    @
    是一个别名运算符,它与仅包含一个元素的列表绑定

    然后,我们将获得:

    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
    
    现在第二个子句(我们的
    格式a@[\u]
    )已经过时了,因为最后一个子句也处理这种情况。因此,我们将函数转换为:

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

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

    谢谢Eric。我添加了格式(a:[])=a:[],它成功了!!很乐意帮忙。添加了关于模式如何工作的更多细节。希望它们在将来的Haskell编码中对您有用!如果使用
    -Wall
    打开警告,GHC会在编译时发出警告,并指出要匹配的缺失案例。推荐。
    format :: String -> String
    format [] = []
    format ('W':'U':xs) = format $ drop 1 xs 
    format (a:xs) = a : format xs