Haskell 运算符声明

Haskell operator declaration

我正在尝试通过带练习的书学习 haskell。我无法通过这个,我不知道是什么问题。所以我要声明一个 << 定义。在 'a' 的除数少于适当的除数 'b' 的情况下,它应该是正确的。就像 6 << 10,6 有 4 个除数,10 有 2 个真除数,所以它应该是 False。我已经为除数和适当的除数做了一个定义,但是当我试图使用它们时,它不会发生。

    divisors :: Integer -> [Integer]
    divisors a = [n | n <- [1..a], a `mod` n == 0]

    properDivisors :: Integer -> [Integer]
    properDivisors a = [n | n <- [2..a `div` 2], a `mod` n == 0]

    (<<) :: Num a => a -> a -> Bool
    x << y = divisors x < properDivisors y

(<<) :: Num a => a -> a -> Bool已修复

您的 << 运算符需要类型 Integral a => a -> a -> Bool,因为 divmod 都需要 Integral,而不仅仅是 Num .如果你不能使用 Integral 约束,那么你将不得不编写自己的 divmod 版本,它们适用于所有 Nums.

如果你注释掉所有的类型签名就可以看到:

> :set +m
> let divisors a = [n | n <- [1..a], a `mod` n == 0]
|     properDivisors a = [n | n <- [2..a `div` 2], a `mod` n == 0]
|     x << y = divisors x < properDivisors y
divisors :: Integral t => t -> [t]
properDivisors :: Integral t => t -> [t]
(<<) :: Integral t => t -> t -> Bool

如果我们检查 divisorsproperDivisors 中使用的函数类型,我们得到

> :t mod
mod :: Integral a => a -> a -> a
> :t div
div :: Integral a => a -> a -> a
> :t (==)
(==) :: Eq a => a -> a -> Bool
> :i Integral
class (Real a, Enum a) => Integral a where
    ...
> :i Real
class (Num a, Ord a) => Real a where
    ...
> :i Ord
class Eq a => Ord a where
    ...

(其他约束没有前提条件)所以为了使用 moddiv 类型必须是 NumEqOrdEnumRealIntegral,因为这是在 Haskell 中设置的类型类层次结构。符合这些约束的两个内置类型是 IntInteger。由于 FloatDouble 没有实现 Integral,但它们确实实现了 Num,因此您无法仅使用 moddiv Num 约束。