2013-10-29 38 views
0

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

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 - >得到空间后的所有东西

任何想法?如果你有任何其他解决这个问题的办法,这将有所帮助。谢谢

+0

这是来自Prelude – viorior

+0

的'单词'功能,但我不能使用单词功能。我需要写它没有文字功能。 – Andrius

回答

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 -----------------| 

类型利弊运营商的是:

(:) :: 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. 
+0

非常感谢,很好的解释。确切地说,我需要你让我度过了美好的一天^^ – Andrius

相关问题