使用"它"产生的模糊类型变量"a0"

CSh*_*per 5 haskell functional-programming ghc ghci

我有以下函数来返回给定数字的因子对

factorPairs:: (RealFrac a, Floating a, Integral a) => a -> [(a, a)]
factorPairs n = map(\x -> (x, div n x)) [y | y <- [1..(ceiling $ sqrt n)], n `rem` y == 0]
Run Code Online (Sandbox Code Playgroud)

当我在ghci中调用函数时,factorPairs 18我得到的运行时错误

   * Ambiguous type variable `a0' arising from a use of `it'
      prevents the constraint `(Floating a0)' from being solved.
      Probable fix: use a type annotation to specify what `a0' should be.
      These potential instances exist:
        instance Floating Double -- Defined in `GHC.Float'
        instance Floating Float -- Defined in `GHC.Float'
    * In the first argument of `print', namely `it'
      In a stmt of an interactive GHCi command: print it
Run Code Online (Sandbox Code Playgroud)

我可以在ghci中对该函数进行硬编码

map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0] 并没有任何问题,但我似乎无法弄清楚为什么我的功能失败.我相信ghci试图告诉我它无法弄清楚要调用哪种类型print,但我正在努力寻找解决方案.

Ale*_*lec 5

这与在Haskell中重载数字文字的事实有关.当您键入map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0]ghci时,18这是一个参数sqrt默认为Double与他人Integer秒.

但是,当你写作

factorPairs:: (RealFrac a, Floating a, Integral a) => a -> [(a, a)]
factorPairs n = map(\x -> (x, div n x)) [y | y <- [1..(ceiling $ sqrt n)], n `rem` y == 0]
Run Code Online (Sandbox Code Playgroud)

您强制所有实例n只有一种类型.然后,问题就变成了没有默认数字类型(实际上我认为通常是数字类型)满足所有这些约束,因此GHC会告诉你它尝试的"可能的实例".解决方案是添加fromIntegral和放松约束:

factorPairs:: Integral a => a -> [(a, a)]
factorPairs n = map(\x -> (x, div n x)) [y | y <- [1..(ceiling $ sqrt $ fromIntegral n)], n `rem` y == 0]
Run Code Online (Sandbox Code Playgroud)