我必须将列表一分为二,得到列表前半部分和列表后半部分的元组(half1, half2)
。当这个列表的长度是奇数时,那么我想使half1
包含比half2
更多的元素。
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(half-[]))的错误,解释器不知道数组是由什么组成的,但我如何才能使它与类型无关?我希望这行给我([],[])。
您尝试过以下操作吗:
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
函数向下取整(楼层)正商,向上取整(天花板)负商:
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
分支。你的职能过于复杂。