我需要打电话floor()
在一个值上,该值只限于类 Floating
,但是 floor()
需要 RealFrac
.
我怎样才能做到这一点?
我非常愿意调用abs()
调用前 floor()
,但仅此一项似乎不足以解决我的约束冲突。
和 coerce
提示这两种表示不能被假定为等价的,这并不奇怪。
看来我需要的是一个带有类型签名的函数:(Floating a, RealFrac b) => a -> b
并且(对我而言)提供一些增强版本的 abs()
似乎是完全合法的。这个签名。
唉,对上述类型签名的 Hoogle 搜索让我两手空空。
有什么想法吗?
谢谢。
:)
最佳答案
考虑以下 Floating
的实例:
import Control.Applicative
instance (Num a) => Num (e -> a) where
(+) = liftA2 (+)
(*) = liftA2 (*)
(-) = liftA2 (-)
abs = fmap abs
signum = fmap signum
negate = fmap negate
fromInteger = pure . fromInteger
instance (Fractional a) => Fractional (e -> a) where
fromRational = pure . fromRational
recip = fmap recip
(/) = liftA2 (/)
instance (Floating a) => Floating (e -> a) where
pi = pure pi
exp = fmap exp
log = fmap log
sin = fmap sin
cos = fmap cos
asin = fmap asin
acos = fmap acos
atan = fmap atan
sinh = fmap sinh
cosh = fmap cosh
asinh = fmap asinh
acosh = fmap acosh
atanh = fmap atanh
演示:
main :: IO ()
main = do
print (sqrt sqrt 81)
let f = sin^2 + cos^2
print (f 42)
(这会输出
3.0000000000000004
和 1.0
。)这使得函数成为
Floating
的实例,但代码推广到所有类型 Monad
s 或 Applicative
s。您的假设函数需要具有类型
(Floating a, RealFrac b) => (e -> a) -> b
在这种情况下。我们可以设置
a
和 b
至 Double
:(e -> Double) -> Double
您如何实现该操作?
还记得我说过这适用于所有 Applicative 吗?我们可以更换
e ->
来自 IO
在上述情况下。然后你最终得到的类型变得更糟:IO Double -> Double
问题是
Floating
可以是任何支持例如exp
或 sin
操作(可能是纯粹的符号操作,例如在语法树上)而 RealFrac
必须是数字(或可转换为数字的东西)。
关于haskell - 是否有类型为 : (Floating a, RealFrac b) => a -> b 的标准 Haskell 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56599241/