How is the Floating typeclass different from Double? - haskell

*User> :t sqrt
sqrt :: Floating a => a -> a
I don't understand what Floating a => a -> a is trying to tell me.
My professor told me sqrt can be thought of like sqrt :: Double -> Double.
And it does act like that but what does Floating a => a -> a mean?
Thank you

A useful thing to try interactively in ghci is the :info <something> command, which can sometimes tell you helpful things.
> :info Floating
class Fractional a => Floating a where
pi :: a
exp :: a -> a
log :: a -> a
sqrt :: a -> a
(**) :: a -> a -> a
---------------------------------------- loads more stuff
-- Defined in ‘GHC.Float’
instance Floating Float -- Defined in ‘GHC.Float’
instance Floating Double -- Defined in ‘GHC.Float’
What does this mean? Floating is a type class. There is more than one type of floating point numbers. Indeed, two come as standard: Float and Double, where Double gives you twice the precision of Float. The a in Floating a stands for any type, and the big list of operations (including sqrt) is an interface which any instance of the class must implement. The fact that sqrt is in the interface for Floating means that it can always and only be used for instances of Floating. That is, to you its type is given as you say
sqrt :: Floating a => a -> a
The => syntax signals a constraint, here Floating a to its left. The type says
for any type a which is an instance of Floating, given an input of type a, the output will have type a
You can specialize this type by filling in a with any type for which the constraint Floating a can be satisfied, so the following are both true
sqrt :: Float -> Float
sqrt :: Double -> Double
Now, Float and Double are represented by different bit-patterns, so the computational mechanisms for taking square roots is different in each case. It's handy not to have to remember different names for the different versions used for different types. The "constraint" Floating a really stands for the record (or dictionary) of the implementations for type a of all the operations in the interface. What the type of sqrt is really saying is
given a type a and a dictionary of implementations for all the Floating operations, I'll take an a and give you an a
and it works by extracting the relevant sqrt implementation from the dictionary and using it on the given input.
So the => signals a function type with an invisible dictionary input just as -> signals a function type with a visible value input. You don't (indeed, you can't) write the dictionary when you use the function: the compiler figures it out from the type. When we write
sqrt :: Double -> Double
we mean the general sqrt function invisibly applied to the Floating Double dictionary.

Floating is a type class. You can think of it as a collection of numeric types which support the following operations:
sqrt, exp, log, (**)
trig functions: sin, cos, tan, asin, acos, atan, pi
hyperboolic trig functions: sinh, cosh, tanh, asinh, acosh, atanh
If you know Java, then you can think of a typeclass like Floating as Java interface.
Examples of types which are in the Floating class:
Float (single precision floating point)
Double
Complex Double
Complex Double are complex numbers where the real and imaginary parts are represented with Double values.
Examples of types which are not in the Floating class:
Int
Char
String
The signature sqrt :: Floating a => a -> a translates roughly as:
For any type a, if a is in the Floating class, then sqrt is a function taking an a and returning an a
This means that you can write code like this:
root a b c = (-b + sqrt (b*b - 4*a*c)) / (2*a)
and you can call root with either Double, Float or Complex Double arguments (provided they are all of the same type). For example:
import Data.Complex
ghci> let root a b c = (-b + sqrt (b*b - 4*a*c)) / (2*a)
ghci> root 1 0 1 :: Double
NaN -- can't represent sqrt -1 as a Double
ghci> root 1 0 1 :: Complex Double
0.0 :+ 1.0 -- sqrt -1 as a Complex number = i
Note how the same expression root 1 0 1 gave different results based on what we forced the return type to be.

Consider this problem instead:
axe :: Log -> (Log, Log)
A function that splits wooden logs in two. Can we generalise this? Turns out we can:
class Splittable l where
axe :: l -> (l,l)
Now axe is not specific to Logs, but can split anything that's soft enough.
instance Splittable Log where
axe = ... -- previous definition, for logs
instance Splittable Neck where
axe = ... -- executable version
For sqrt it's similar: this function sure makes sense for (positive) Doubles, but it can also operate on more general types of numbers. For instance,
> sqrt (-1) :: Double
NaN -- urgh... negative numbers don't have real roots!
> :m +Data.Complex
> sqrt (-1) :: Complex Double
(- 0.0) :+ 1.0

You can think of the part to the left of => as a set of constraints.
Floating a means: the type a must be an instance of the Floating type class. I assume you know what type classes are. If not, see this or search for "haskell type classes"
So: Floating a => a -> a means: given any type a that is an instance of the Floating type class, this function has type a -> a. Because Haskell has more than one type of floating point numbers, this "more generic" type is used. One instance of Floating is indeed, Double.

The Floating a bit is a constraint requiring the type a to belong to the class of types that represent, or are viewable as, floating point numbers, that is, a belongs to the Floating class, or, a is an instance of Floating.
You can, sort of, think of type classes like interfaces — a type a either implements that "interface" or it doesn't; now sqrt simply works on any type a that implements Floating.
But don't get too carried away with this analogy — it ends almost as quickly as it begins: there are more differences between, say Java, interfaces and Haskell type classes than there are similarities, but the analogy is useful for "getting on board".
To sum up, Floating a => a -> a means: a function from values of any type a to values of that same type a (i.e. a -> a), for as long as the type a resembles a floating point.
Doing :i Floating in a GHCi REPL will, in addition to the structure of the Floating type class, show you a list of the types that implement it:
Prelude> :i Floating
class Fractional a => Floating a where
... LOTS OF FUNCTION DECLARATIONS ...
-- Defined in ‘GHC.Float’
instance Floating Float -- Defined in ‘GHC.Float’
instance Floating Double -- Defined in ‘GHC.Float’
Constraints have a language of their own in Haskell and can be composed, so you can have (Floating a, Floating c, Foo a, Bar [b], Baz c) => a -> [b] -> (a, c) or some other crazy imaginary type signature.

Related

What is the correct way to use fromIntegral to convert an Integer to real-fractional types?

I am trying to use fromIntegral to convert from Integer to a real-fractional type. The idea is to have a helper method to later be used for the comparison between two instances of a Fraction (whether they are the same).
I have read some of the documentation related to:
fromIntegral :: (Integral a, Num b) => a -> b
realToFrac :: (Real a, Fractional b) => a -> b
Where I am having trouble is taking the concept and make an implementation of the helper method that takes a Num data type with fractions (numerator and denominator) and returns what I think is a real-fractional type value. Here is what I have been able to do so far:
data Num = Fraction {numerator :: Integer, denominator :: Integer}
helper :: Num -> Fractional
helper (Fraction num denom) = realToFrac(num/denom)
You need to learn about the difference between types and type classes. In OO languages, both are kind of the same concept, but in Haskell they're not.
A type contains concrete values. E.g. the type Bool contains the value True.
A class contains types. E.g. the Ord class doesn't contain any values, but it does contain the types which contain values that can be compared.
In case of numbers in Haskell it's a bit confusing that you can't really tell from the name whether you're dealing with a type or a class. Fractional is a class, whereas Rational is a type (which is an instance of Fractional, but so is e.g. Float).
In your example... first let's give that type a better name
data MyRational = Fraction {numerator :: Integer, denominator :: Integer}
...you have two possibilities what helper could actually do: convert to a concrete Rational value
helper' :: MyRational -> Rational
or a generic Fractional-type one
helper'' :: Fractional r => MyRational -> r
The latter is strictly more general, because Rational is an instance of Fractional (i.e. you can in fact use helper'' as a MyRational -> Rational function, but also as a MyRational -> Double function).
In either case,
helper (Fraction num denom) = realToFrac(num/denom)
does not work because you're trying to carry out the division on integer values and only then converting the result. Instead, you need to convert the integers to something fractional and then carry out the division in that type.

Question about the argument type of sqrt and round

following the signature:
sqrt :: Floating a => a -> a
why is (sqrt 2) legal? Isn't the number 2 a Integer which definitely doesn't satisfy Floating? Same Question about round, round (sqrt 2) is legal, sqrt returns type Floating but round needs ReadFrac.
round :: (RealFrac a, Integral b) => a -> b
The literal 2 is of type Num a => a. That is, it can be any numerical type. Specifically, Haskell will take the integer value 2 and call fromInteger on it (which is defined for any Num). So when you write
sqrt 2
Internally, what's happening is
sqrt (fromInteger 2) :: Floating a => a
And if you force the value, such as in GHCi, you'll get a Double since that's the default for Floating.
Likewise, the type of round (sqrt 2) is going to be Integral b => b and is going to require the sqrt 2 type to be RealFrac a => a. There exist types which are both RealFrac and Floating, so that's not a contradiction. In particular, GHC will happily default to Double here for the same reason as before. If you force the value to be printed, the entire result (Integral b => b) will default to Integer.
It's important to remember that all of these are universally quantified. Floating a => a doesn't mean "this is some floating type and that's all I know". It means "if you have any floating type, I can produce a value of that type". You get to choose which floating type to use, so if a constraint comes along later and says the value is also RealFrac a => a, that's fine because we've simply constrained ourselves to be both Floating and RealFrac. This is contrary to a language like Java, where if I have a value of some interface type, say Comparable, then all I can conclude is that it's some Comparable type, not that it works for all of them.

What's the difference between the classes Floating and Fractional in Haskell?

What is the difference is between the Floating and Fractional classes in Haskell?
Very roughly:
Fractional is the class of types that can represent (exactly or at least in a decent approximation) any rational number. It may ad lib also be able to represent other numbers, but that's not important.In other terms, it's just the class of number types that have a division operation; since it's a subclass of Num it follows from this that the types must contain the rational numbers.
Floating is the class of number types that are closed under limits in the Cauchy sense, i.e. complete spaces. This is necessary to do any sort of calculus. The methods of the Floating class are functions that are mathematically defined as limits, namely infinite sums (which are the limits of the sequence of partial sums of taylor series).Since you can define the real numbers as limits of sequences of rational numbers and because again Floating is a subclass of Fractional, any Floating type is able to represent (again, at least to a decent approximation) any real number.
A good way to visualise the difference is through topology: Floating types are connected spaces, i.e. they form a continuum. What this means for floating point numbers is: every value is understood as a whole interval of real numbers (because floating-point always has some uncertainty). When you lay these intervals side by side, you tile the entire real numbers (at least to ±10300) without gaps.
By contrast, some Fractional types are not connected. In particular, Rational can exactly represent all its (rational-number) values, so each value is just an “infinitely small point”. You can never cover the entire real line with such points, and you can not compute functions like sin or log since the result of these functions is usually a non-rational real number.
It's worth pondering a bit what this “decent approximation” means. The Haskell standard doesn't define this. This story about every floating point number representing a whole interval of real numbers captures it quite well IMO. More generally, we might say: Num/Fractional/Floating are the classes of types that represent equivalance classes of integer/rational/real numbers. In fact, these classes need not even be “small” intervals: in particular the finite types like Word32 or the standard Int can be understood in a modular arithmetic sense, manifesting in results like (2^70 :: Int) == 0, i.e. the equivalence classes are then numbers spaces by a multiple of 264.
In cases like Integer or Rational, the equivalence classes actually contain only a single element, i.e. the numbers are represented exactly. For real numbers, this is actually also possible, but much more tricky, it's called exact real arithmetic. There are libraries such as aern that do this.
The definitions of Fractional and Floating can be found in the documentation of the Prelude:
class Num a => Fractional a where
(/) :: a -> a -> a
recip :: a -> a
fromRational :: Rational -> a
Fractional numbers, supporting real division.
[...]
class Fractional a => Floating a where
pi :: a
exp :: a -> a
log :: a -> a
sqrt :: a -> a
(**) :: a -> a -> a
logBase :: a -> a -> a
sin :: a -> a
cos :: a -> a
tan :: a -> a
asin :: a -> a
acos :: a -> a
atan :: a -> a
sinh :: a -> a
cosh :: a -> a
tanh :: a -> a
asinh :: a -> a
acosh :: a -> a
atanh :: a -> a
Trigonometric and hyperbolic functions and related functions.
[...]
So to translate that into English: A Fractional is any kind of number for which I can define a division:
(/) :: Fractional a => a -> a -> a
That can for instance be the case for floating point numbers, but also for fractions (where a fraction has a numerator and denominator). This is not the case for Int because if dividing an Int by an Int does not always produce an Int (well technically floating point division on a computer is not exact, but that is another story).
A subset of Fractional numbers are Floating numbers where trigonometric are defined. It is for instance impossible that the sin of a fraction always produces a fraction: a sin is defined as an sum over an infinite sequence. Only for a very limited number of cases (like sin 0) it holds. Basically the only numbers on a computer for which trigonometric are defined (approximatively) are floating point numbers.

What is wrong with this simple type definition? (Expecting one more argument to...)

basic.hs:
areaCircle :: Floating -> Floating
areaCircle r = pi * r * r
Command:
*Main> :l basic.hs
[1 of 1] Compiling Main ( Sheet1.hs, interpreted )
Sheet1.hs:2:15:
Expecting one more argument to `Floating'
In the type signature for `areaCircle':
areaCircle :: Floating -> Floating
Failed, modules loaded: none.
I see that areaCircle :: Floating a => a -> a loads as expected. Why is the above version not acceptable?
Because your version does not actually supply a type. Floating is a type class. If you want to allow any Floating, then Floating a => a -> a is correct. Otherwise you can try either Float -> Float or Double -> Double.
Just to flesh it out a bit more: Floating a => a -> a says not only that your function accepts any Floating type, but that it returns the same type it is passed. This must be true even if you narrow the type. For example, you would not be able to use Float -> Double without doing some additional conversions
Floating isn't a type, it's a type class. You can't use a type class as a type like you are. When you say Floating in Haskell you're asserting that the following type is an instance of the class. So, for example, you could write the code as
areaCircle :: Floating a => a -> a
areaCircle r = pi * r * r
which you can read informally as: for any type a, if a is an instance of the class Floating then areaCircle can be used as a function from a to a.
You can think of Floating as a bit like an adjective. It describes types. But you're trying to use it like a noun, ie. as a type itself.
http://en.wikipedia.org/wiki/Type_class

Exponentiation in Haskell

Can someone tell me why the Haskell Prelude defines two separate functions for exponentiation (i.e. ^ and **)? I thought the type system was supposed to eliminate this kind of duplication.
Prelude> 2^2
4
Prelude> 4**0.5
2.0
There are actually three exponentiation operators: (^), (^^) and (**). ^ is non-negative integral exponentiation, ^^ is integer exponentiation, and ** is floating-point exponentiation:
(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
(**) :: Floating a => a -> a -> a
The reason is type safety: results of numerical operations generally have the same type as the input argument(s). But you can't raise an Int to a floating-point power and get a result of type Int. And so the type system prevents you from doing this: (1::Int) ** 0.5 produces a type error. The same goes for (1::Int) ^^ (-1).
Another way to put this: Num types are closed under ^ (they are not required to have a multiplicative inverse), Fractional types are closed under ^^, Floating types are closed under **. Since there is no Fractional instance for Int, you can't raise it to a negative power.
Ideally, the second argument of ^ would be statically constrained to be non-negative (currently, 1 ^ (-2) throws a run-time exception). But there is no type for natural numbers in the Prelude.
Haskell's type system isn't powerful enough to express the three exponentiation operators as one. What you'd really want is something like this:
class Exp a b where (^) :: a -> b -> a
instance (Num a, Integral b) => Exp a b where ... -- current ^
instance (Fractional a, Integral b) => Exp a b where ... -- current ^^
instance (Floating a, Floating b) => Exp a b where ... -- current **
This doesn't really work even if you turn on the multi-parameter type class extension, because the instance selection needs to be more clever than Haskell currently allows.
It doesn't define two operators -- it defines three! From the Report:
There are three two-argument exponentiation operations: (^) raises any number to a nonnegative integer power, (^^) raises a fractional number to any integer power, and (**) takes two floating-point arguments. The value of x^0 or x^^0 is 1 for any x, including zero; 0**y is undefined.
This means there are three different algorithms, two of which give exact results (^ and ^^), while ** gives approximate results. By choosing which operator to use, you choose which algorithm to invoke.
^ requires its second argument to be an Integral. If I'm not mistaken, the implementation can be more efficient if you know you are working with an integral exponent. Also, if you want something like 2 ^ (1.234), even though your base is an integral, 2, your result will obviously be fractional. You have more options so that you can have more tight control over what types are going in and out of your exponentiation function.
Haskell's type system does not have the same goal as other type systems, such as C's, Python's, or Lisp's. Duck typing is (nearly) the opposite of the Haskell mindset.

Resources