我在haskell中有我的isPrime函数,如下所示:
isPrime = \x -> length (filter (\y -> x `mod` y == 0) [2..(x - 1)]) == 0
它工作正常。
但当我即将优化这样的功能时:
isPrime = \x -> length (filter (\y -> x `mod` y == 0) [2..(floor(sqrt x))]) == 0
发生了一些错误,为什么会发生这种情况?
嗯,错误代码是:
Euler.hs:34:41:
No instance for (Integral a0) arising from a use of ‘mod’
The type variable ‘a0’ is ambiguous
Relevant bindings include
y :: a0 (bound at Euler.hs:34:34)
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
In the first argument of ‘(==)’, namely ‘x `mod` y’
In the expression: x `mod` y == 0
In the first argument of ‘filter’, namely ‘(\ y -> x `mod` y == 0)
Euler.hs:34:49:
No instance for (Eq a0) arising from a use of ‘==’
The type variable ‘a0’ is ambiguous
Relevant bindings include
y :: a0 (bound at Euler.hs:34:34)
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in ‘GHC.Real’
instance Eq () -- Defined in ‘GHC.Classes’
instance (Eq a, Eq b) => Eq (a, b) -- Defined in ‘GHC.Classes’
...plus 23 others
In the expression: x `mod` y == 0
In the first argument of ‘filter’, namely ‘(\ y -> x `mod` y == 0)
In the first argument of ‘length’, namely
‘(filter (\ y -> x `mod` y == 0) [2 .. (floor (sqrt x))])’
Euler.hs:34:52:
No instance for (Num a0) arising from the literal ‘0’
The type variable ‘a0’ is ambiguous
Relevant bindings include
y :: a0 (bound at Euler.hs:34:34)
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus three others
In the second argument of ‘(==)’, namely ‘0’
In the expression: x `mod` y == 0
In the first argument of ‘filter’, namely ‘(\ y -> x `mod` y == 0)
Euler.hs:34:55:
No instance for (Enum a0)
arising from the arithmetic sequence ‘2 .. (floor (sqrt x))’
The type variable ‘a0’ is ambiguous
Relevant bindings include
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance Enum Double -- Defined in ‘GHC.Float’
instance Enum Float -- Defined in ‘GHC.Float’
instance Integral a => Enum (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 7 others
In the second argument of ‘filter’, namely
‘[2 .. (floor (sqrt x))]’
In the first argument of ‘length’, namely
‘(filter (\ y -> x `mod` y == 0) [2 .. (floor (sqrt x))])’
In the first argument of ‘(==)’, namely
‘length (filter (\ y -> x `mod` y == 0) [2 .. (floor (sqrt x))])’
Euler.hs:34:60:
No instance for (RealFrac a0) arising from a use of ‘floor’
The type variable ‘a0’ is ambiguous
Relevant bindings include
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance RealFrac Double -- Defined in ‘GHC.Float’
instance RealFrac Float -- Defined in ‘GHC.Float’
instance Integral a => RealFrac (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
In the expression: (floor (sqrt x))
In the second argument of ‘filter’, namely
‘[2 .. (floor (sqrt x))]’
In the first argument of ‘length’, namely
‘(filter (\ y -> x `mod` y == 0) [2 .. (floor (sqrt x))])’
Euler.hs:34:66:
No instance for (Floating a0) arising from a use of ‘sqrt’
The type variable ‘a0’ is ambiguous
Relevant bindings include
x :: a0 (bound at Euler.hs:34:12)
isPrime :: a0 -> Bool (bound at Euler.hs:34:1)
Note: there are several potential instances:
instance Floating Double -- Defined in ‘GHC.Float’
instance Floating Float -- Defined in ‘GHC.Float’
In the first argument of ‘floor’, namely ‘(sqrt x)’
In the expression: (floor (sqrt x))
In the second argument of ‘filter’, namely
‘[2 .. (floor (sqrt x))]’
Failed, modules loaded: none.
似乎mod功能和楼层功能存在一些问题?
答案 0 :(得分:2)
你的第二个函数是一个没有签名推断的奇怪类型:
isPrime :: (RealFrac a, Integral a, Floating a) => a -> Bool
我不确定任何类型是所有这些类的实例(Int和Double绝对不是)。所以你的功能很好,你无法提供它正在运行的值。