本文介绍了在haskell中组成floor和sqrt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我的问题: 我只是在学习haskell(我自己,为了好玩)。 b $ b 如何定义一个函数 flrt =(floor。sqrt) 当我在一个文件中尝试并编译时,GCHi会抱怨以下内容: AKS.hs:11:9:由于使用floor引起的(RealFrac Integer)没有实例可能的修正:为(RealFrac Integer)添加实例声明在'(。)'的第一个参数中,即'floor'在表达式中:(floor。sqrt) In 'flrt'的等式:flrt =(floor。sqrt) AKS.hs:11:17:没有使用(浮点整数)的实例`sqrt'可能的修正:为(Floating Integer)添加一个实例声明在'(。)'的第二个参数中,即`sqrt'在表达式中:(floor。sqrt )在等式中`flrt':flrt =(floor。 sqrt) 我不明白为什么结果函数不只是Int - > Int。 我刚完成我的第二学年,完成了基础PL课程。我听说过,但还没有完全获得类型。我试着阅读了一些haskell的教程,但它都超出了我的头。 - 我也不明白monad是什么。 (我搜索出来的很多其他问题都谈到了这些) P.P.S。 - 我的完整源代码 bar = \ a b - >如果(2 ^ a)> b then(a-1) else bar(a + 1)b foo = bar 1 flrt :: Integer - >整数 flrt =(floor。sqrt) aks target = if(target then putStrNot a Prime.\\\\\\ else if elem(mod target 10)[0,2,4,5,6,8] then putStrComposite \\\\\\ else if(elem target)[a ^ b | a - [3,5 ..(flrt target)],b 然后putStrComposite \\\\\\ - - } else putStrfiller 解决方案 正如copumpkin所说,在这里转换为浮点数可能实际上是一个坏主意,因为这会伴随着精度的损失,因此即使舍入,也可能会产生不正确的结果,导致足够大的整数输入。 我假设您处理的所有数字都至少足够小,以至于 是它们的一些浮点表示形式,例如全部是< 10 300 。但是,例如 Prelude> (sqrt.fromInteger $ 10 ^ 60 :: Double)^ 2 1000000000000000039769249677312000395398304974095154031886336 Prelude> { - and not - } 10 ^ 60 { - ==(10 ^ 30)^ 2 ==(sqrt $ 10 ^ 60)^ 2 - } 1000000000000000000000000000000000000000000000000000000000000 pre> 关于绝对差异, way 关闭。尽管如此,它对数字本身来说确实是一个相当好的近似值,所以您可以将其用作算法的快速确定的起点以找到确切的结果。您可以使用整数 s来实现Newton / Raphson(在这种情况下为AKA Heron): flrt :: Integer - >整数 - flrt x≈√x,flrt x ^ 2≤x flrt x = approx(round。(sqrt :: Double-&Double;)fromInteger $ x) where r | ctrl x = r |否则= approx $ r - diff 其中ctrl = r ^ 2 diff =(ctrl - x)//(2 * r) - ∂/∂xx²= 2x a // b = a`div`b + if(a> 0)==(b> 0)then 1 else 0 - always from 0 $ b 现在可以根据需要运行: * IntegerSqrt> (flrt $ 10 ^ 60)^ 2 10000000000000000000000000000000000000000000000000000000000 牛顿 - 拉夫逊修正在这里是必要的,以防止陷入无限递归。 I'm just learning haskell (on my own, for fun) and I've come up against a wall.My Question:How can I define a function flrt = (floor . sqrt)When I try it in a file and compile, GCHi complains with the following:AKS.hs:11:9: No instance for (RealFrac Integer) arising from a use of `floor' Possible fix: add an instance declaration for (RealFrac Integer) In the first argument of `(.)', namely `floor' In the expression: (floor . sqrt) In an equation for `flrt': flrt = (floor . sqrt)AKS.hs:11:17: No instance for (Floating Integer) arising from a use of `sqrt' Possible fix: add an instance declaration for (Floating Integer) In the second argument of `(.)', namely `sqrt' In the expression: (floor . sqrt) In an equation for `flrt': flrt = (floor . sqrt)I don't understand why the resulting function isn't just Int -> Int.I've just finished my second year of CS and done a basic PL course. I've heard of, but don't quite get types yet. I tried reading through a few haskell tutorials but it's all going above my head.P.S. - I also don't understand what a monad is. (a lot of the other questions that my search turned up talked about these)P.P.S. - My full sourcebar = \a b -> if (2^a) > b then (a-1) else bar (a+1) bfoo = bar 1flrt :: Integer -> Integerflrt = (floor . sqrt)aks target = if (target < 2) then putStr "Not a Prime.\n\n" else if elem (mod target 10) [0,2,4,5,6,8] then putStr "Composite\n\n" else if (elem target) [a^b | a <- [3,5..(flrt target)], b <- [1.. (foo target)]] then putStr "Composite\n\n"--} else putStr "filler" 解决方案 As copumpkin remarked, it might actually be a bad idea to convert to floating point here, because this comes with loss of precision and therefore might, even with rounding, yield incorrect results for sufficiently large integer inputs.I assume all numbers you're dealing with will at least be small enough that there is some floating-point representation for them, e.g. all are < 10300. But, for instancePrelude> round(sqrt.fromInteger$10^60 :: Double) ^ 21000000000000000039769249677312000395398304974095154031886336Prelude> {- and not -} 10^60 {- == (10^30)^2 == (sqrt$10^60) ^ 2 -}1000000000000000000000000000000000000000000000000000000000000Which is way off, in terms of absolute difference. Still it's certainly a rather good approximation relative to the numbers themselves, so you can use it as a quickly determined starting point for an algorithm to find the exact result. You can implement Newton/Raphson (in this case AKA Heron) with Integers:flrt :: Integer -> Integer -- flrt x ≈ √x, with flrt x^2 ≤ x < flrt(x+1)^2flrt x = approx (round . (sqrt::Double->Double) . fromInteger $ x) where approx r | ctrl <= x, (r+1)^2 > x = r | otherwise = approx $ r - diff where ctrl = r^2 diff = (ctrl - x) // (2*r) -- ∂/∂x x² = 2x a//b = a`div`b + if (a>0)==(b>0) then 1 else 0 -- always away from 0This now works as desired:*IntegerSqrt> (flrt $ 10^60) ^ 21000000000000000000000000000000000000000000000000000000000000The division always away from 0 in the Newton-Raphson correction is here necessary to prevent getting stuck in an infinite recursion. 这篇关于在haskell中组成floor和sqrt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-15 04:52