2013-11-28 51 views
-2

我必須將列表分成兩半,導致列表的前半部分和列表的後半部分的元組(half1, half2)。當這個列表的長度很奇怪,那麼我想讓half1包含比half2更多的元素。爲什麼在這個例子中天花板和地板操作員之間沒有區別? (Haskell)

halve :: [a] -> ([a],[a]) 
halve [] = ([],[]) 
halve xs = 
    if (((length(xs) `mod` 2)==1)) 
    then(take (ceiling(toRational(length(xs) `div` 2))) xs, drop(ceiling(toRational(length(xs) `div` 2))) xs) 
    else ((take (floor(toRational(length(xs) `div` 2))) xs, drop (floor(toRational(length(xs) `div` 2))) xs)) 
main = do 
putStrLn(show (halve [1,2,3])) gives me [1],[2,3] instead of [1,2],[3] 
putStrLn(show (halve [])) gives me an error 

這讓我覺得在mod操作或天花板操作中會出現一些截斷。 我知道,對於putStrLn(show(halve []))的錯誤,解釋器不知道數組是由什麼組成的,但我怎樣才能使它的類型無關緊要?我想這條線給我([],[])。

+0

1)你不需要明確地將所有內容加在一起。 Haskell很聰明。而不是編寫'if(((length(xs)\'mod''2)== 1))''你可以簡單地寫'如果長度爲xs \'mod \'2 == 1' 2)使用'print' 'putStrLn(show ...)'。 3)瞭解功能組成和應用 –

+1

請注意,「給我一個錯誤」是沒有用的。不僅有一個錯誤,你知道嗎?如果你相信或不相信,有時候知道**你得到了什麼**錯誤是很重要的。 – Ingo

+1

如果您找到了解決問題的方法,那麼您應該接受答案或者提供自己的答案並接受答案。不要編輯你的問題,並提到它已經解決了。這對其他人沒有幫助。也不要從你的問題中刪除重要的信息。這可能會讓某些答案出現在上下文之外。我回滾了你的改變。 –

回答

1

你有沒有試過如下:

halve :: [a] -> ([a], [a]) 
halve xs = let n = div (length xs + 1) 2 
      in (take n xs, drop n xs) 

-- or alternatively 

halve :: [a] -> ([a], [a]) 
halve xs = splitAt (div (length xs + 1) 2) xs 

div功能幾輪下來(地板)正商和圍捕(ceils)陰性商:

div 5 2 => 2 
div -5 2 => -2 
div 6 2 => 3 
div -6 2 => -3 

halve功能就像你預計它會:

halve []  => ([], []) 
halve [1..5] => ([1,2,3], [4,5]) 
halve [1..6] => ([1,2,3], [4,5,6]) 

我不明白你爲什麼需要if then else分支。你的功能不必要的複雜。

相關問題