我在Haskell中编写了一个合并排序,它在使用数字而不是单词时起作用,我认为它会。使用单词和字母时,我只是得到“不在范围内”。我做错了什么?
这是我的代码:
merge :: Ord a => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| x <= y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
mergeSort :: Ord a => [a] -> [a]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs
= merge (mergeSort top) (mergeSort bottom)
where
(top, bottom) = splitAt (length xs `div` 2) xs
答案 0 :(得分:4)
你输入这样的话吗?
[this,is,an,example,sentence]
语法不正确。如果要输入文字字符串,则必须用双引号("
)封装它:
["this","is","an","example","sentence"]
如果这不是您的错误,请随意忽略此答案。
答案 1 :(得分:3)
您的代码运行正常。
但是我建议在一次通过中拆分列表,而不使用length
。当然,这里的顺序并不重要,只是我们有两个大小相同的列表。你可以这样做:
splitList [] = ([],[])
splitList [x] = ([x],[])
splitList (x:y:zs) = let (xs,ys) = splitList zs in (x:xs, y:ys)
...或尾递归...
splitList zs = go zs [] [] where
go [] xs ys = (xs, ys)
go [x] xs ys = (x:xs, ys)
go (x:y:zs) xs ys = go zs (x:xs) (y:ys)
...或使用索引......
splitList xs = (go even, go odd) where
go f = map snd $ filter (f.fst) $ indexed
indexed = zip [0..] xs
......或使用折叠...
import Data.List
splitList zs = snd $ foldl' go (True,([],[])) zs where
go (True,(xs,ys)) x = (False,(x:xs,ys))
go (False,(xs,ys)) x = (True,(xs,x:ys))