我正在尝试在上限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
时抛出此错误。
答案 0 :(得分:2)
定义功能没有错误。当您要使用该功能时,错误会更多。
如果我们看一下您构造的函数的类型,我们会看到:
multiplesOf :: (RealFrac t, Integral t) => t -> t -> [t]
因此,此处输入和输出值的类型都应为Integral
和RealFrac
。因此,该数字应为Integral
,但同时支持实数除法。没有太多类型可以满足这些要求。
此问题源于您在此处使用(/)
和floor
的事实,这暗示max
和num
是RealFrac
,但是结果floor
中的Integral
是num
,然后再次用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 i
和Integer maxSize = arrList.size()
。