Haskell中的类型声明

Haskell中的类型声明,haskell,Haskell,我刚开始学哈斯克尔。我决定为自己设定一个目标,实现我的一个旧算法 首先,我编写了以下代码 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 small

我刚开始学哈斯克尔。我决定为自己设定一个目标,实现我的一个旧算法

首先,我编写了以下代码

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
Haskell编译器已确定primes返回一个浮点列表。 然而,当我试图告诉它

phi :: [Integer] -> [Integer]
这正是我想要的,编译器有一个问题:

No instance for (Floating Integer)
  arising from a use of `sqrt` at ...

那么,我如何表示phi以整数列表作为输入,以整数列表作为输出,生成无限多的整数列表?

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

Haskell没有在不同的数字类型之间进行自动转换,因为这在Haskell的类型系统中是不可能的。

看看:

天花板
也应该是诀窍(正如Fuzzxl指出的allready)


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

尝试将
sqrt
与其他函数相结合,比如
fromIntegral
floor
,获取正确类型的平方根函数。给出的代码似乎不起作用——我猜这只是因为转录错误,因此对其进行格式化,因为您说它起作用了,但是
(tail phi$reverse smallprimes)
似乎没有意义,
减号中的
LT
大小写也没有意义。对不起,我犯了一个抄写错误。现在试试看。我只是意识到如果我改变了(假设
$
介于
tail
phi
之间,这确实是一件奇怪的事情。即使
primes
的参数是浮点,这个参数也不可能传递到
phi
。所以我怀疑这段代码是否真的是你编译的代码?是的——通常是一个或两个很好的转换sion函数是您所需要的所有函数——诀窍在于:-)感谢本文的链接——看起来很有趣,并且懒递归筛选类型算法在Haskell中非常好。实际上我尝试了floor,即我写的,即我写的(floor sqrt x)而不是sqrt x,但这也不起作用——Haskell拒绝编译它。实际上floor是对的,因为我的意思是让素数x返回{p prime:p@Victomoriller:我不确定它是否适合你的算法,但一个常见的技巧是坚持使用整数,只取
p
而不是取
x
的平方根@Victor Miller:如果你按字面意思写
floor sqrt x
,那么你可能得到的错误是因为它被解析为
(floor sqrt)x
。空格分隔标识符是左关联函数应用程序,其优先级高于内置语法以外的任何东西。哦,请注意,遵循@hammar关于平方值而不是平方根的建议不仅可以避免转换,还可以避免精度损失--
整数是一个任意大小的整数ger类型,而浮点类型是通常的有限精度处理。不过,在这种特殊情况下,我想您可能不会超过
Double
可以准确表达的值范围……是否有兴趣在其中获取Haskell Wiki的链接?我想这会给答案带来价值,我可以删除我的几乎是redund的内容ant这样回答…?谢谢。我缺少的是积分。但我真的希望允许素数的参数是实数(即浮点数),因为这是数论中的典型操作。我尝试将(x<2)改为((上限x)<2)考虑到这一点,我仍然得到了浮点答案。的确,所有数字类型之间没有自动转换,但实际上,您可以在一些类型上实现这种效果。您可以定义一个多参数类型类,它可以在不同类型的数字上运行所需的所有操作(+),(-)等。(这是在一些经典论文中,可能是关于相关类型的?我忘了,对不起。)
No instance for (Floating Integer)
  arising from a use of `sqrt` at ...
smallprimes = primes . ceiling . sqrt . fromIntegral $ x