Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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
Haskell 哈斯克尔:把字符和列表粘在一起?_Haskell - Fatal编程技术网

Haskell 哈斯克尔:把字符和列表粘在一起?

Haskell 哈斯克尔:把字符和列表粘在一起?,haskell,Haskell,我这里有一个代码: toWords :: String -> [String] toWords "" = [] toWords (nr1 : rest) | nr1 == ' ' = toWords rest | otherwise = [nr1] : toWords rest “toWords”函数只需删除所有空格并返回包含所有单词的列表。但这种情况会发生: *Main>toWords“你好吗?” [“H”、“o”、“w”、“a”、“r”、“e”、“

我这里有一个代码:

toWords :: String -> [String]
toWords "" = []
toWords (nr1 : rest)
    | nr1 == ' ' = toWords rest
    | otherwise = [nr1] : toWords rest
“toWords”函数只需删除所有空格并返回包含所有单词的列表。但这种情况会发生:

*Main>toWords“你好吗?”

[“H”、“o”、“w”、“a”、“r”、“e”、“y”、“o”、“u”和“?”]


这仅仅是我,还是你正试图从Prelude中重新发明“words”函数?

两个问题——首先,为什么你的输出是多态的?它似乎总是一个
字符串的列表,而不是一个
字符串的列表。我不太熟悉Haskell类型的推理内部结构;尝试将签名更改为
String->String
String->[Char]
,然后查看是否有效

第二,当你这样做的时候,你应该清楚地看到你的实现有点不顺利;即使它确实有效,它也会简单地返回原始字符串,并删除所有空格


如果确实要返回字符串列表,则需要有一个helper函数来构建当前单词,然后在当前字符为字符串时将整个单词添加到输出列表中。因为您这样做似乎是为了学习(否则,只需使用Prelude函数),所以我不会给出一个列表,但从这里应该不难理解。

您的类型应该是String->[String]或[Char]->[[Char]]

您的输入是一个字符串(字符列表),您的输出是一个字符串列表(字符列表)

这里的类型意味着它将字符串映射到任何类型,这不是真的

编辑:或者,您可以使用:

splitBy :: [a] -> a -> [[a]]
splitBy [] sep = []
splitBy (nr1 : rest) if nr1 == sep then splitBy rest sep else nr1 : (splitBy rest sep)
它是多态的,并通过任何分隔符拆分列表。(代码未经测试)因此
splitBy“string of words”'
应返回[“string”、“of”、“words”]

最后,这是一个恼人的问题,它有一个明显而愚蠢的错误[]代替了[]。功能版本是:

splitBy [] sep = [[]]
splitBy (nr1 : rest) sep = if nr1 == sep 
    then [] : splitBy rest sep 
    else (nr1 : head (splitBy rest sep)) : tail (splitBy rest sep)

这样:
splitBy“List of things”''==>[“List”,“of”,“things”]

思考一下它的作用:

它遍历字符串中的每个字符

| nr1 == ' ' = toWords rest
如果字符是空格,则跳过该字符

| otherwise = [nr1] : toWords rest
否则,它将创建一个仅包含该字符的字符串,然后继续对该字符串中的其余字符执行此操作

| nr1 == ' ' = toWords rest
您想要的是将单词中的字符累积到单个列表中,而不是为每个字符创建一个新列表

下面是一个示例,说明如何做到这一点:

toWords "" = []
toWords (' ':rest) = toWords rest
toWords text       = let (word, rest) = break (== ' ') text
                     in word : toWords rest

哇,我不知道。但我仍然好奇我的代码有什么问题:)您打印的错误消息与您的代码不匹配。您的代码有
nr1:toWords rest
,但错误消息提到
[nr1]:toWords rest
@Tom Lokhorst您是对的,错误消息是错误的。谢谢:)splitBy的类型实际上是
(等式a)=>[a]->a->[[a]]]
。它只适用于Eq的实例。在实践中可能不是什么问题——只是指出它。