What is the Haskell RealFloat type used for?

Learn You A Haskell provides an example of calculating your BMI.

bmiTell :: (RealFloat a) => a -> a -> String bmiTell weight height | bmi <= skinny = "You're underweight, you emo, you!" | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!" | bmi <= fat = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2 (skinny, normal, fat) = (18.5, 25.0, 30.0) 

When I tried to do this example myself, I used (Num a) => a -> a -> String as the type signature for the method. However, this generated the following error:

 Could not deduce (Ord a) arising from a use of '<=' from the context (Num a) bound by the type signature for bmiTell :: Num a => a -> a -> String at scratch.hs:96:12-38 Possible fix: add (Ord a) to the context of the type signature for bmiTell :: Num a => a -> a -> String 

I could not resolve the error using only the Num and Ord classes. Why do I need to use RealFloat typeclass to make this piece of code work? What is special about RealFloat that is not covered by Num ?

+5
source share
2 answers

While Num not enough, RealFloat indeed excessive for this example. Fractional , which is necessary for (/) , is good enough:

 GHCi> :t (/) (/) :: Fractional a => a -> a -> a 

The corresponding signature will then be:

 bmiTell :: (Fractional a, Ord a) => a -> a -> String 

RealFloat is a class for floating point types, and Fractional covers everything that supports real division. Double is RealFloat (as well as a Fractional , since it is a superclass from RealFloat ). The Ratio type for rational numbers, available from Data.Ratio , is an example of Fractional , which is not RealFloat .

See also: Ben's answer, which considers why the book may have used RealFloat , rather than perhaps the simpler alternative shown here.

+6
source

In addition to / , as indicated in the answer to the duplicate, you use non-integer literals like 18.5 . They cannot be used like every type of Num (e.g. 18.5 :: Integer ), so you cannot promise that your function can handle any type of Num that the caller likes.

I suspect that the book uses RealFloat simply because it also implies Ord (via RealFrac and Real ), so only one restriction had to be written. A lot of limitations could make the example look more complex and intimidating, and the function is not the point of the exercise.

+3
source

Source: https://habr.com/ru/post/1261208/


All Articles