我需要在一个值上调用floor()
,该值仅被限制为Floating
类,但floor()
需要RealFrac
。
我该怎么做?
我非常愿意在调用abs()
之前先调用floor()
,但是仅此一项似乎不足以解决我的约束冲突。coerce
提示不能将这两种表示形式假定为等效,这不足为奇。
看来我需要的是带有类型签名的函数:(Floating a, RealFrac b) => a -> b
在我看来,给此签名一些增强版abs()
似乎是完全合法的。
las,对上述类型签名的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
或Applicative
的所有类型。您的假设函数需要具有以下类型
(Floating a, RealFrac b) => (e -> a) -> b
在这种情况下。我们可以将
a
和b
设置为Double
:(e -> Double) -> Double
您如何执行该操作?
还记得我说过的适用于所有应用程序吗?在上述情况下,我们可以将
e ->
替换为IO
。然后,您最终得到的类型会变得更糟:IO Double -> Double
问题是
Floating
可以是任何支持例如exp
或sin
操作(可能是纯符号操作,例如在语法树上),而RealFrac
必须是数字(或可转换为数字的东西)。关于haskell - 是否存在类型为: (Floating a, RealFrac b)=> a-> b的标准Haskell函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56599241/