在Haskell中输入声明

时间:2011-09-22 17:55:55

标签: haskell

我刚开始学习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将整数列表作为输入,并且输出会产生无限的整数列表?

2 个答案:

答案 0 :(得分:6)

代码中的问题是,sqrt期望浮点数并返回相同的值。您必须使用转换类型的包装器才能使其工作。 (这基本上就是错误信息所说的):

smallprimes = primes . ceiling . sqrt . fromIntegral $ x

Haskell在不同的数字类型之间没有自动转换,因为Haskell所具有的类型系统不可能这样做。

答案 1 :(得分:2)

看一看:Converting numbers

ceiling也应该是技巧(正如FUZxxl指出的那样)

恕我直言,这里的困难部分是我们用来通过指向你的目标来转换类型的语言--Haskell在这里以一种令人费解的方式切换逻辑......