I need to call floor() on a value, which is only constrained to be of class Floating, but floor() requires RealFrac.
How can I do this?
I'm perfectly willing to call abs() before calling floor(), but this alone seems insufficient to solve my constraint conflict.
And coerce complains that the two representations cannot be assumed equivalent, which isn't surprising.
It seems what I need is a function with type signature:
(Floating a, RealFrac b) => a -> b
And it seems (to me) perfectly legitimate to give some augmented version of abs() this signature.
Alas, a Hoogle search on the above type signature left me empty handed.
Any thoughts?
Thanks.
:)
In Haskell, every statement is considered as a mathematical expression and the category of this expression is called as a Type. You can say that "Type" is the data type of the expression used at compile time. To learn more about the Type, we will use the ":t" command.
Haskell has two integral types, namely Int and Integer . Int is the type of limited-precision integers; this means that there is a smallest integer of type Int , namely minBound , and a greatest integer of type Int , namely maxBound .
The Eq class defines equality ( == ) and inequality ( /= ). All the basic datatypes exported by the Prelude are instances of Eq , and Eq may be derived for any datatype whose constituents are also instances of Eq . The Haskell Report defines no laws for Eq .
The shows functions return a function that prepends the output String to an existing String . This allows constant-time concatenation of results using function composition.
Consider the following instance of 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
Demo:
main :: IO ()
main = do
print (sqrt sqrt 81)
let f = sin^2 + cos^2
print (f 42)
(This outputs 3.0000000000000004 and 1.0.)
This makes functions an instance of Floating, but the code generalizes to all types that are Monads or Applicatives.
Your hypothetical function would need to have the type
(Floating a, RealFrac b) => (e -> a) -> b
in this instance. We could set a and b to Double:
(e -> Double) -> Double
How do you implement that operation?
Remember that I said this generalizes to all Applicatives? We can replace e -> by IO in the above instances. Then the type you end up with gets even worse:
IO Double -> Double
The problem is that Floating can be anything that supports e.g. exp or sin operations (which could be purely symbolic operations e.g. on a syntax tree) while RealFrac must be a number (or something convertible to a number).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With