我刚开始学习Haskell。我决定为自己设定一个实现我的旧算法http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.79.7006&rep=rep1&type=pdf
的目标首先,我编写了以下代码
phi [] = [1..]
phi (p:pl) = (phi pl) `minus` (map (p*) $ phi pl)
primes x
| x < 2 = []
| otherwise = smallprimes ++ (takeWhile (<=x) $tail $ phi $ reverse smallprimes)
where smallprimes = primes $ sqrt x
minus (x:xs) (y:ys) = case (compare x y) of
LT -> x : minus xs (y:ys)
EQ -> minus xs ys
GT -> minus (x:xs) ys
minus xs _ = xs
除了素数列表以浮点形式出现之外,它按预期运行!有点想法告诉我,因为sqrt的签名是
sqrt :: (Floating a) => a -> a
Haskell编译器已经确定primes正在返回一个浮点列表。 但是,当我试图告诉它
时phi :: [Integer] -> [Integer]
这就是我想要的,编译器有一个问题:
No instance for (Floating Integer)
arising from a use of `sqrt` at ...
那么我如何表示phi将整数列表作为输入,并且输出会产生无限的整数列表?
答案 0 :(得分:6)
代码中的问题是,sqrt
期望浮点数并返回相同的值。您必须使用转换类型的包装器才能使其工作。 (这基本上就是错误信息所说的):
smallprimes = primes . ceiling . sqrt . fromIntegral $ x
Haskell在不同的数字类型之间没有自动转换,因为Haskell所具有的类型系统不可能这样做。
答案 1 :(得分:2)
ceiling
也应该是技巧(正如FUZxxl指出的那样)
恕我直言,这里的困难部分是我们用来通过指向你的目标来转换类型的语言--Haskell在这里以一种令人费解的方式切换逻辑......