我需要在一个值上调用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.00000000000000041.0。)

这使函数成为Floating的实例,但是代码可以推广到MonadApplicative的所有类型。

您的假设函数需要具有以下类型
(Floating a, RealFrac b) => (e -> a) -> b

在这种情况下。我们可以将ab设置为Double:
(e -> Double) -> Double

您如何执行该操作?

还记得我说过的适用于所有应用程序吗?在上述情况下,我们可以将e ->替换为IO。然后,您最终得到的类型会变得更糟:
IO Double -> Double

问题是Floating可以是任何支持例如expsin操作(可能是纯符号操作,例如在语法树上),而RealFrac必须是数字(或可转换为数字的东西)。

关于haskell - 是否存在类型为: (Floating a, RealFrac b)=> a-> b的标准Haskell函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56599241/

10-11 21:51