在这个例子中,为什么天花板和地板操作员之间没有区别? (Haskell的) [英] Why isn't there a difference between the ceiling and floor operators in this example? (Haskell)
问题描述
我必须将列表分成两半,导致列表的前半部分和列表的后半部分(half1,half2)
的元组。当这个列表的长度是奇数时,我想让 half1
包含比 half2
更多的元素。
I have to split a list in half, resulting in a tuple of the first half of the list and the second half of the list (half1, half2)
. When the length of this list is odd, then I want to make half1
contain more elements than 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(halve []))的错误,解释器不知道数组是由什么组成的,但我怎样才能使它的类型无关紧要?我想这条线给我([],[])。
This makes me think that there is some truncation going on in the mod operation or ceiling operation. I know that for the error with putStrLn(show (halve [])), the interpreter doesn't know what the array is made of, but how can I make it so that the type does not matter? I would like that line to give me ([],[]).
推荐答案
>
Have you tried the following:
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)负商数:
The div
function rounds down (floors) positive quotients and rounds up (ceils) negative quotients:
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
分支。您的功能不必要的复杂。
I don't see why you need an if then else
branch. Your function is unnecessarily complicated.
这篇关于在这个例子中,为什么天花板和地板操作员之间没有区别? (Haskell的)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!