为什么multiplesOf num max = [num * k | k <-[1..floor(max / num)]]抛出错误?

时间:2018-10-27 10:58:02

标签: haskell

我正在尝试在上限num下创建数字max的所有倍数的集合。我在Haskell中编写了以下函数:

multiplesOf num max = [num*k | k <- [1..floor (max/num)]]

为什么此函数在运行时会引发以下错误?如何解决?

<interactive>:26:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
  prevents the constraint ‘(Show a0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘a0’ should be.
  These potential instances exist:
    instance Show Ordering -- Defined in ‘GHC.Show’
    instance Show Integer -- Defined in ‘GHC.Show’
    instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
    ...plus 22 others
    ...plus 18 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it

例如,输入multiplesOf 3 1000时抛出此错误。

1 个答案:

答案 0 :(得分:2)

定义功能没有错误。当您要使用该功能时,错误会更多。

如果我们看一下您构造的函数的类型,我们会看到:

multiplesOf :: (RealFrac t, Integral t) => t -> t -> [t]

因此,此处输入和输出值的类型都应为IntegralRealFrac。因此,该数字应为Integral,但同时支持实数除法。没有太多类型可以满足这些要求。

此问题源于您在此处使用(/)floor的事实,这暗示maxnumRealFrac,但是结果floor中的Integralnum,然后再次用multiplesOf :: Integral i => i -> i -> [i] multiplesOf num max = [num*k | k <- [1..div max num]] 将数字超出此范围。

但是,您可以通过使用div :: Integral a => a -> a -> a来减少类型约束的数量。因此,这是整数除法,结果被截断为负无穷大,因此我们可以实现以下功能:

multiplesOf :: (Num n, Enum n) => n -> n -> [n]
multiplesOf num max = [num, (num+num) .. max]

或者我们甚至可以免除进行除法,乘法等操作的麻烦,并使用为我们工作的范围表达式:

Integral i

后者的约束更少,因为Real i意味着Enum iInteger maxSize = arrList.size()