哈斯克尔分部

时间:2011-09-10 00:54:51

标签: haskell division

我在Haskell中创建了一个函数,它只将列表中的evens减半,我遇到了问题。当我运行编译器时,它抱怨你不能执行int的划分,并且我需要一个小数int类型声明。我已经尝试将类型声明更改为float,但这只是生成了另一个错误。我已经在下面包含了该函数的代码,并希望获得任何形式的帮助。

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x/2:halfEvens xs

感谢您的阅读。

2 个答案:

答案 0 :(得分:38)

使用执行整数除法的div

halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
                 | otherwise = x `div` 2 : halfEvens xs

(/)函数需要类型在Fractional类中的参数,并执行标准除法。 div函数需要其类型在Integral类中的参数,并执行整数除法。

更确切地说,divmod向负无穷大方向前进。他们的堂兄quotrem的行为类似于integer division in C并向零舍入。进行模运算时divmod通常是正确的(例如,在计算给定日期的星期几时),而quotrem稍快一些(我认为)。

在GHCi中玩一下:

> :t div
div :: Integral a => a -> a -> a
> :t (/)
(/) :: Fractional a => a -> a -> a
> 3 / 5
0.6
> 3 `div` 5
0
> (-3) `div` 5
-1
> (-3) `quot` 5
0
> [x `mod` 3 | x <- [-10..10]]
[2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1]
> [x `rem` 3 | x <- [-10..10]]
[-1,0,-2,-1,0,-2,-1,0,-2,-1,0,1,2,0,1,2,0,1,2,0,1]

答案 1 :(得分:0)

我应该补充一点,使用map可以简化代码。

HalfIfEven n
  | even n = n `div` 2
  | otherwise = n

halfEvens = map halfIfEven