在Haskell中不起作用的素数s函数

6vl6ewon  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(125)

我是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.我必须通过添加fromIntegralx/2来修改因子的绘制列表:

f <- [2..round (fromIntegral x/2)]


现在,为什么我必须声明,即使我已经使用roundx/2转换为整数?
编辑:如果[2..round (x/2)]有问题,那么这段代码是否可以正常工作:

ii = 33
samLis = [2..round (ii/2)]

hwamh0ep

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**中使用它),虽然人们可以在技术上“制造”这样的类型,但这没有意义:数字类型是整数或分数,而不是两者。
如果你这样实现它:

primes = [x | x <- [2 .. 100], null [f | f <- [2 .. round (fromIntegral x / 2)], 0 == rem x f]]

字符串
我们就完了
然而,主要检查远非有效:例如,我们可以在√n处停下来进行检查。
但为什么其他功能没有出现这个问题呢?就像这个功能刚刚工作得很好。我没有声明listCom的类型。
因为它使用了类型默认规则,将使用Integer,而且因为你没有在任何函数中使用x来强制它不能满足的类型约束,所以没有问题。

相关问题