在Haskell中输入声明

Vic*_*ler 7 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
Run Code Online (Sandbox Code Playgroud)

这个函数按预期运行,除了素数列表是浮点数!有点想法告诉我,因为sqrt的签名是

sqrt :: (Floating a) => a -> a
Run Code Online (Sandbox Code Playgroud)

Haskell编译器已经确定primes正在返回一个浮点列表.但是,当我试图告诉它时

phi :: [Integer] -> [Integer]
Run Code Online (Sandbox Code Playgroud)

这就是我想要的,编译器有一个问题:

No instance for (Floating Integer)
  arising from a use of `sqrt` at ...
Run Code Online (Sandbox Code Playgroud)

那么我如何表示phi将整数列表作为输入,并且输出会产生无限的整数列表?

fuz*_*fuz 6

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

smallprimes = primes . ceiling . sqrt . fromIntegral $ x
Run Code Online (Sandbox Code Playgroud)

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