Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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模式匹配概念_String_Haskell_Pattern Matching_String Split - Fatal编程技术网

String 文本拆分器背后的Haskell模式匹配概念

String 文本拆分器背后的Haskell模式匹配概念,string,haskell,pattern-matching,string-split,String,Haskell,Pattern Matching,String Split,我想知道这个代码片段背后的模式匹配概念: split :: String -> Char -> [String] split [] delim = [""] split (c:cs) delim | c == delim = "" : rest | otherwise = (c : head rest) : tail rest where rest = split cs delim 我知道head返回列表的第一个元素,tai

我想知道这个代码片段背后的模式匹配概念:

 split :: String -> Char -> [String]
 split [] delim = [""]
 split (c:cs) delim
     | c == delim = "" : rest
     | otherwise = (c : head rest) : tail rest
       where
         rest = split cs delim

我知道
head
返回列表的第一个元素,
tail
返回其余元素。但我仍然无法理解它的功能。这将获取一个字符串,并将其从给定字符分解为一个字符串列表。

以下形式可能更清楚:

split [] delim = [""]    -- a list containing only an empty String
split (c:cs) delim = let (firstWord:moreWords) = split cs delim
                     in if c == delim
                           then "" : firstWord : moreWords
                           else (c:firstWord) : moreWords
函数遍历输入字符串,将每个字符与分隔符进行比较。如果当前字符不是定界字符,则将其固定在拆分字符串剩余部分后产生的第一个单词(可能为空)的前面;如果当前字符是定界字符,则将向拆分剩余部分后的结果前面添加一个空字符串

例如,
split“abc cde”的评估过程如下

split "abc cde" ' '
    ~> 'a' == ' ' ? No, next guard
    ~> ('a' : something) : somethingElse
其中,
某物
某物
稍后将通过拆分剩余的
“bc cde”来确定。查看第一个字符后,确定无论最终结果是什么,它的第一个条目都以
'a'开头。接下来决定剩下的

split "bc cde" ' '
    ~> ('b' : something1) : somethingElse1
       where (something1 : somethingElse1) = split "c cde" ' '
现在,结果第一个条目的前两个字符是已知的。然后从下一步开始,确定
something1
'c'
开头。最后我们得到了一个分隔符,在这种情况下,结果的第一个元素是在不参考后面的递归调用的情况下确定的,并且在递归中只剩下结果的其余部分

制定算法的另一种方法是(感谢@dave4420的建议)


因此,将空字符串添加到from将拆分字符串。我的意思是,字符串被分隔成一系列字符串的方式。?如果找到定界字符,它将返回什么。。。?如示例所示,一个名为“abc cde”的字符串需要与空格分隔。。然后,当它有一个“”时,它将返回“”、“cde”或“cde”。。head是否包含字符串列表?@Gihan
拆分“abc cde”'
将生成
[“abc”,“cde”]
。我不确定我是否理解你的下一个问题,但如果我理解:
head
获取任何类型的列表,在
split
中,它确实在
String
列表中调用。是的。关于下一个问题,是这样的。我要拆分的字符串是
“abc cde”
,因为它有7个字符,这有7个递归阶段。将从最后阶段开始。它将返回
“E”
。第6次重复将返回
E:F:Null
,如
“EF”
中所示。第五个将返回
D:E:F
,如
中的“DEF”
所示。然后是第四层的空间。然后它将是
:“DEF”
对的。这就是问题所在。它会以
(“”,“DEF”)
“DEF”
的形式从那里返回吗?如果它是
(“”,“DEF”)
,那么在第三级,它本身将是
C::“DEF”
返回
“C”,“DEF”
对吗?我不知道。每个(有限且完全[spine]定义的)列表以空列表结尾
[]
。每当到达分隔符(或输入的结尾)时,就会插入一个空列表(由
Char
s组成,一个空
字符串
)来标记一个块的结尾。
split input delim = foldr combine [""] input
  where
    combine c rest@(~(wd : wds))
        | c == delim = "" : rest
        | otherwise  = (c : wd) : wds