我是Haskell的新手,但我知道C。我指的是 Learn You a Haskell for Great Good 作为学习源代码,目前正在学习“列表理解”。因为我可以很容易地在C中编写素数程序,所以我用以下代码在Haskell中进行了同样的尝试:
primes = [x | x <- [2..100], null [f | f <- [2..round (x/2)], 0 == rem x f]]
--it creates a list of prime numbers upto 100. `f` denotes factors.
--working principle: this code adds those numbers to the main list who have no factors (excluding 1 and the number itself.
字符串
但它在我的GHCi中显示了一个大错误:
train.hs:84:20:
No instance for (Enum t0)
arising from the arithmetic sequence ‘2 .. 100’
The type variable ‘t0’ is ambiguous
Relevant bindings include primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance forall (k :: BOX) (s :: k). Enum (Data.Proxy.Proxy s)
-- Defined in ‘Data.Proxy’
instance Integral a => Enum (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Enum Ordering -- Defined in ‘GHC.Enum’
...plus 8 others
In the expression: [2 .. 100]
In a stmt of a list comprehension: x <- [2 .. 100]
In the expression:
[x |
x <- [2 .. 100],
null [f | f <- [2 .. round (x / 2)], 0 == rem x f]]
train.hs:84:21:
No instance for (Num t0) arising from the literal ‘2’
The type variable ‘t0’ is ambiguous
Relevant bindings include primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
...plus three others
In the expression: 2
In the expression: [2 .. 100]
In a stmt of a list comprehension: x <- [2 .. 100]
train.hs:84:49:
No instance for (Integral t0) arising from a use of ‘round’
The type variable ‘t0’ is ambiguous
Relevant bindings include
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the expression: round (x / 2)
In the expression: [2 .. round (x / 2)]
In a stmt of a list comprehension: f <- [2 .. round (x / 2)]
train.hs:84:57:
No instance for (Fractional t0) arising from a use of ‘/’
The type variable ‘t0’ is ambiguous
Relevant bindings include
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Fractional Double -- Defined in ‘GHC.Float’
instance Fractional Float -- Defined in ‘GHC.Float’
In the first argument of ‘round’, namely ‘(x / 2)’
In the expression: round (x / 2)
In the expression: [2 .. round (x / 2)]
train.hs:84:65:
No instance for (Eq t0) arising from a use of ‘==’
The type variable ‘t0’ is ambiguous
Relevant bindings include
f :: t0 (bound at train.hs:84:40)
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance (Eq a, Eq b) => Eq (Either a b)
-- Defined in ‘Data.Either’
instance forall (k :: BOX) (s :: k). Eq (Data.Proxy.Proxy s)
-- Defined in ‘Data.Proxy’
instance (GHC.Arr.Ix i, Eq e) => Eq (GHC.Arr.Array i e)
-- Defined in ‘GHC.Arr’
...plus 28 others
In the expression: 0 == rem x f
In a stmt of a list comprehension: 0 == rem x f
In the first argument of ‘null’, namely
‘[f | f <- [2 .. round (x / 2)], 0 == rem x f]’
Failed, modules loaded: none.
型
抱歉,我重新检查了我的代码,但考虑到语法,它看起来很好。
然而,当我将相同的代码放入我的ghci>
中时,结果有点不同:
Prelude> let primes = [x | x <- [2..100], null [f | f <- [2..round (x/2)], 0 == rem x f]]
Prelude> primes
<interactive>:12:1:
No instance for (Integral t0) arising from a use of ‘it’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
型
如果我能认识到我的错误,我会很高兴。
和我课本上的代码一样:--
1.我必须像这样将primes
声明为整数列表:
primes :: [Integer]
型
但为什么其他功能没有出现这个问题呢?就像这个功能刚刚工作得很好。我没有声明listCom
的类型:
listCom = [2*x | x <- [1..50], rem x 3 == 0]
型
1.我必须通过添加fromIntegral
和x/2
来修改因子的绘制列表:
f <- [2..round (fromIntegral x/2)]
型
现在,为什么我必须声明,即使我已经使用round
将x/2
转换为整数?
编辑:如果[2..round (x/2)]
有问题,那么这段代码是否可以正常工作:
ii = 33
samLis = [2..round (ii/2)]
型
1条答案
按热度按时间hwamh0ep1#
现在,为什么我必须声明,即使我已经使用round将x/2转换为整数?
它不是转换
x/2
,而是转换x
。实际上,**(/) :: Fractional a => a -> a -> a
适用于 * 分数 * 数,而Integer
或任何其他整数都不是Fractional
数,因此如果没有fromIntegral
,则需要x
既是Fractional
(因为你在x/2
中使用它)和Integral
(因为你在rem :: Integral a => a -> a -> a
**中使用它),虽然人们可以在技术上“制造”这样的类型,但这没有意义:数字类型是整数或分数,而不是两者。如果你这样实现它:
字符串
我们就完了
然而,主要检查远非有效:例如,我们可以在√n处停下来进行检查。
但为什么其他功能没有出现这个问题呢?就像这个功能刚刚工作得很好。我没有声明
listCom
的类型。因为它使用了类型默认规则,将使用
Integer
,而且因为你没有在任何函数中使用x
来强制它不能满足的类型约束,所以没有问题。