我是Haskell的新手,也是一般的函数式编程.另外,我知道上面的问题非常相似,但我无法在任何地方找到解决问题的方法.以下代码用于查找数字输入的因子:
fc4 :: Double -> IO ()
check :: Double -> Double -> IO ()
fc4 a = check a (sqrt a)
check a b = if rem a b == 0 then print (b, div a b) else print () >> if b > 1 then check a (b-1) else putStrLn ("Done.")
Run Code Online (Sandbox Code Playgroud)
我尝试使用每种可能的组合切换Double到Integer和返回,但每个都失败并出现相同的错误:
No instance for (Integral Double) arising from a use of 'rem'
Run Code Online (Sandbox Code Playgroud)
我也试过明确地使用fromIntegral和toInteger参数rem,但我没有尝试避免这个问题.我还通过文档看到类型rem是Integral a => a -> a -> a,所以似乎使用相同的类型a并且b将始终有效,无论是Double或Integer.
我有事吗?我犯了一些可怕的菜鸟错误吗?作为参考,这是我希望实现的C++版本.提前致谢!
你可以简单地替换Double用Integer的类型签名,因为你需要使用它的类型是实例的值Integral类型的类,它定义div和rem.但是,sqrt只返回作为Floating类型类实例的值,并且没有任何类型都是两者的实例.
简单的解决方案是使用ceiling一个略大于的积分值sqrt n,这不会影响算法的正确性.
check :: Integer -> Integer -> IO ()
check a b = ... -- same as before
fc4 :: Integer -> IO ()
--fc4 a = check a (ceiling (sqrt a)) -- because I didn't bother testing
fc4 a = check a (floor (sqrt (fromIntegral a)))
Run Code Online (Sandbox Code Playgroud)