将字符串放入Haskell中的列表中

时间:2013-10-29 13:56:24

标签: haskell

我需要创建自己的单词函数。它需要字符串并放入有空间的列表中。例如,字符串“我需要帮助”将导致[“i”,“need”,“help”]。 定义必须完全

anything :: String -> [String]

我目前想出的愚蠢的解决方案看起来像这样(也不起作用)

test :: String -> [String]
test d = beforep d : (test (afterp d)) : []

beforep :: String -> String
beforep d = takeWhile (/=' ') d
afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[] then []
      else tail(dropWhile (/=' ') d)

测试 - >使用尾递归

beforep - >得到一切直到第一空间

afterp - >获得空间后的一切

有什么想法吗?如果您对此问题有任何其他解决方案,那将有所帮助。谢谢

1 个答案:

答案 0 :(得分:5)

你差不多了。如果我尝试按原样运行您的代码,我会得到:

test.hs:2:23:
    Couldn't match expected type `Char' with actual type `String'
    Expected type: String
      Actual type: [String]
    In the return type of a call of `test'
    In the first argument of `(:)', namely `(test (afterp d))'

所以检查第2行:

test d = beforep d : (test (afterp d)) : []
--                                      ^
-- This is the problem -----------------|

cons运算符的类型是:

(:) :: a -> [a] -> [a]

您的test函数已经返回[String],您不想尝试将其置于空列表中。这意味着返回类型为[[String]]

请改为尝试:

test d = beforep d : (test (afterp d))

在更改之后,它会编译,但是当您运行test "i need help"时,您将获得无限列表:

["i","need","help","","","","","","","",""...

问题是您需要在test中包含一个基本案例,当您将其传递给空列表时会停止。这是工作代码:

test :: String -> [String]
test [] = []
test d = beforep d : (test (afterp d))

beforep :: String -> String
beforep d = takeWhile (/=' ') d

afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[]     -- Slightly reformatted
             then []                        -- to improve readability,
             else tail(dropWhile (/=' ') d) -- no real change.