因使用“it”而产生的不明确类型变量“a0”
Ambiguous type variable `a0' arising from a use of `it'
我有以下函数来return给定数字的因子对
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]
当我在 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
我可以在 ghci 中对函数进行硬编码
map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0]
没有任何问题,但我似乎无法弄清楚为什么我的功能失败了。我相信 ghci 试图告诉我它无法弄清楚用什么类型调用 print
但我正在努力寻找解决方案。
这与 Haskell 中的数字文字超载有关。当您将 map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0]
键入 ghci
时,作为 sqrt
参数的 18
默认为 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]
您强制 n
的所有实例只有一种类型。然后,问题就变成了根本没有满足所有这些约束的默认数字类型(事实上,我认为通常是数字类型),因此 GHC 告诉你 "possible instances" 它会尝试。解决办法是加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]
消除类型错误的另一种方法是消除 sqrt
的使用。由于 Haskell 是惰性的,您可以简单地迭代 [1..n]
,当除数大于商时停止。
factorPairs :: Integral a => a -> [(a, a)]
factorPairs n = takeWhile (uncurry (>=)) [ (n `div` d, d) | d <- [1..n], n `mod` d == 0]
uncurry (>=)
只是一种奇特的写法 \(q, d) -> q >= d
.
如果您以单子形式编写此代码,则可以使用 divMod
通过单个函数 all 获取商和余数。
factorPairs n = takeWhile (uncurry (>=)) $ do
d <- [1..n]
let (q, r) = n `divMod` d
guard $ r == 0
return (q, d)
我有以下函数来return给定数字的因子对
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]
当我在 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
我可以在 ghci 中对函数进行硬编码
map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0]
没有任何问题,但我似乎无法弄清楚为什么我的功能失败了。我相信 ghci 试图告诉我它无法弄清楚用什么类型调用 print
但我正在努力寻找解决方案。
这与 Haskell 中的数字文字超载有关。当您将 map(\x -> (x, div 18 x)) [y | y <- [1..(ceiling $ sqrt 18)], 18 `rem` y == 0]
键入 ghci
时,作为 sqrt
参数的 18
默认为 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]
您强制 n
的所有实例只有一种类型。然后,问题就变成了根本没有满足所有这些约束的默认数字类型(事实上,我认为通常是数字类型),因此 GHC 告诉你 "possible instances" 它会尝试。解决办法是加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]
消除类型错误的另一种方法是消除 sqrt
的使用。由于 Haskell 是惰性的,您可以简单地迭代 [1..n]
,当除数大于商时停止。
factorPairs :: Integral a => a -> [(a, a)]
factorPairs n = takeWhile (uncurry (>=)) [ (n `div` d, d) | d <- [1..n], n `mod` d == 0]
uncurry (>=)
只是一种奇特的写法 \(q, d) -> q >= d
.
如果您以单子形式编写此代码,则可以使用 divMod
通过单个函数 all 获取商和余数。
factorPairs n = takeWhile (uncurry (>=)) $ do
d <- [1..n]
let (q, r) = n `divMod` d
guard $ r == 0
return (q, d)