Haskell datatype conversion problems - haskell

I am currently learning Haskell and have been writing a couple of very simple programs to practice as I go along. One of these programs is the one I have bellow:
import System.IO
main = do
putStrLn "Give me year: "
y <- getLine
let res = show . calcPop $ read y
putStrLn ("Population in " ++ y ++ " will be " ++ res)
pop :: Float
pop = 307357870.0
secInYear :: Float
secInYear = 365.0 * 24.0 * 60.0 * 60.0
bRate :: Float
bRate = secInYear / 7.0
dRate :: Float
dRate = secInYear / 13.0
iRate :: Float
iRate = secInYear / 35.0
calcPop :: Float -> Float
calcPop year = let years = year - 2010 in (years*bRate + years*iRate + pop - years*dRate)
What it does is take a year after 2010 and calculate the estimated population in that year, and as it is right now it works fine and all except that as you may have noticed EVERY single number is cast as a float. Now it is pretty ridiculous to do this since there is no reason to have the current population, the number of seconds in a year or the year itself for that matter as anything but ints, unfortunately though when I had it that way I was getting compiler error with the / function saying something about fractional int and with the * function saying it inferred a float as the first parameter. Now I had understood that Haskell like other languages when encountering operations involving ints and floats would just change the int to act like a float which aperantly didn't happen here. Could someone explain why I was getting these errors and how I can get ints and floats to cooperate since evidently I still don't have a good enough grasp of the Haskell type system to do it myself?

Haskell types are strict; it never automatically converts a type for you, except that integer literals are automatically wrapped in fromIntegral. Instead, you may want to use more type-appropriate operations such as `div` when you only need to deal with Int/Integer, and fromIntegral to promote to Float or Double when needed.
(Syntax note: `function` converts a prefix function into an infix operator.)

For integer division in Haskell you use div or quot.

From the Haskell 98 language report:
An integer literal represents the
application of the function
fromInteger to the appropriate value
of type Integer. Similarly, a floating
point literal stands for an
application of fromRational to a value
of type Rational (that is, Ratio
Integer).
This means a "7" in the source code becomes "(fromInteger 7)" and "1.5" becomes "(fromRational (3 Ratio.% 2))". The numerical operations such as (+) and (/) have type signatures like "a->a->a" meaning they two arguments of perfectly identical types and return the same type as given. These standard operators can never do things like add a Float to an Int. You can write a (fromIntegral) to try and promote an Int-like-type to things like a Double or Float.

Related

Machine precision in Haskell

I googled "Haskell machine precision" and didn't find any information about how to get the machine precision in Haskell. Is there a built-in way to get it?
Otherwise I implemented it as follows (I translated some C++ code found on a serious site):
machinePrecision :: Double
machinePrecision = until isSmall half 1.0
where
isSmall :: Double -> Bool
isSmall x = 1.0 + x / 2.0 == 1.0
half :: Double -> Double
half x = x / 2.0
Is it a correct way to get the machine precision of double numbers in Haskell?
Some packages, including ieee754 and numeric-limits define a value epsilon that is the smallest representable x such that 1 and 1+x can be distinguished. That appears to be the machinePrecision value you're trying to calculate.
You can use these packages if you want, but you can also just use the two-line definition:
epsilon :: Double
epsilon = 2.2204460492503131e-16
It will never be anything else, notwithstanding any documentation in the Prelude about hypothetical Doubles that aren't IEEE754 doubles.
If you need an equivalent value for Float the definition is:
epsilon :: Float
epsilon = 1.19209290e-07
These definitions are exactly the same ones used in the ieee754 package, except in that package they're instances of a class method.
The values in Lennart Augustsson's numeric-limits package are calculated on the fly using encodeFloat and decodeFloat, a principled but "somewhat excessive" approach.
You can also use the following alternative definitions, which are equivalent:
epsilon :: Double
epsilon = 2**(-52)
epsilon :: Float
epsilon = 2**(-23)
If you are worried about portability to other Haskell implementations, start by patting yourself on the back for being one of the eight people on the planet writing Haskell for non-GHC targets, and then take comfort in the fact that there are no existing Haskell implementations whose Double is something other than an IEEE double.

What is the right way to convert from Double to Fixed in Haskell?

I have some code that uses Centi for its currency type. It receives Doubles from an Excel spreadsheet using the xlsx package. I want to convert these Doubles into Centis correctly. I have tried using realToFrac, and for the most part it works, but occasionally it's out by a cent:
λ realToFrac (-1372.92 :: Double) :: Centi
-1372.93
I can guess that the problem is in the binary representation of that decimal number not being exact, and that I shouldn't be using Double to represent currency in the first place, but I don't have control of that part. So what is a fail-safe way of doing the conversion?
Maybe not the best way but one is to round to the closest integer after adjusting for the desired precision:
floatToCenti :: Double -> Centi
floatToCenti = floatToFixed
floatToFixed :: HasResolution a => Double -> Fixed a
floatToFixed x = y where
y = MkFixed (round (fromInteger (resolution y) * x))
-- reusing y as the dummy argument of resolution

converting list of type Integer to list of type Int

i'm trying to convert this list [1..20] from [Integer] to [Int]
map fromInteger [1..20]
however this still gives me a list of Integers
This on its own converts 2 which is Integer type to Int
fromInteger 2 :: Int
What's wrong
In Haskell, values can – just like functions – be polymorphic.
This idea is familiar to most programmers for the numerical operators: nobody finds it strange that 5 + 6 works, yielding and integer, just as fine as 3.14159 + 2.71828 works yielding a float. But in languages like C this is done pretty much ad-hoc, just because this special case is so handy. This brings a lot of problems with it, in particular when you write things like 1/12, which will carry out the / as integer-division, resulting in 0. Clearly not the intended thing when ou use it in something like
for (double hourWay = 0; hourWay<1; hourWay += 1/12)
double theta = hourWay * 2 * pi;
...
So programmers have to resort to ugly hacks like writing out the fraction in decimal, or explicitly making one of the numbers float (1.0 / 12.0, urgh!).
Haskell does this automatically for us: when it sees the result will be a double (that's explicitly written out in hourWays declaration) it makes no sense to start that calculation with integers, so it interprets 1 and 12 as floating-point right away. No problem with that since the integers certainly form a subset of the reals1. You can directly access this functionality by giving explicit type signatures:
Prelude> 4 :: Int
4
Prelude> 4 :: Double
4.0
Note that :: Double does not convert the number. 4 by itself does not have any particular type at all, it's polymorphic: whatever number type you want, 4 is a valid description; this is expressed in the type system by the signature
Prelude> :t 4
4 :: Num a => a
And in particular, this means
Prelude> :t [1..20]
[1..20] :: (Num t, Enum t) => [t]
is also polymorphic, which allows you to write
Prelude> [1..20] :: [Int]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
Prelude> [1..20] :: [Double]
[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0]
Only when you don't give any signature, ghci will default to the "safest bet", which is Integer.
So in the case of [1..20] you don't need fromInteger at all. You would need it though if some elements weren't given directly as literals, but external constants / arguments of fixed type Integer.
Prelude> let x = 13 :: Integer
Prelude> :t [1..12]++[x]++[14..20]
[1..12]++[x]++[14..20] :: [Integer]
Prelude> map fromInteger ([1..12]++[x]++[14..20]) :: [Int]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
This works again with any numerical result type you request, because although x prevents [1..12]++[x]++[14..20] from being polymorphic, fromInteger re-introduces that.
Prelude> :t map fromInteger ([1..12]++[x]++[14..20]) :: [Int]
map fromInteger ([1..12]++[x]++[14..20]) :: Num b => [b]
1Which doesn't actually mean Double forms a subtype of Integer or even Int... it doesn't; but this becomes a problem only for big numbers.

Haskell Type Coercion

I trying to wrap my head around Haskell type coercion. Meaning, when does can one pass a value into a function without casting and how that works. Here is a specific example, but I am looking for a more general explanation I can use going forward to try and understand what is going on:
Prelude> 3 * 20 / 4
15.0
Prelude> let c = 20
Prelude> :t c
c :: Integer
Prelude> 3 * c / 4
<interactive>:94:7:
No instance for (Fractional Integer)
arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: 3 * c / 4
In an equation for `it': it = 3 * c / 4
The type of (/) is Fractional a => a -> a -> a. So, I'm guessing that when I do "3 * 20" using literals, Haskell somehow assumes that the result of that expression is a Fractional. However, when a variable is used, it's type is predefined to be Integer based on the assignment.
My first question is how to fix this. Do I need to cast the expression or convert it somehow?
My second question is that this seems really weird to me that you can't do basic math without having to worry so much about int/float types. I mean there's an obvious way to convert automatically between these, why am I forced to think about this and deal with it? Am I doing something wrong to begin with?
I am basically looking for a way to easily write simple arithmetic expressions without having to worry about the neaty greaty details and keeping the code nice and clean. In most top-level languages the compiler works for me -- not the other way around.
If you just want the solution, look at the end.
You nearly answered your own question already. Literals in Haskell are overloaded:
Prelude> :t 3
3 :: Num a => a
Since (*) also has a Num constraint
Prelude> :t (*)
(*) :: Num a => a -> a -> a
this extends to the product:
Prelude> :t 3 * 20
3 * 20 :: Num a => a
So, depending on context, this can be specialized to be of type Int, Integer, Float, Double, Rational and more, as needed. In particular, as Fractional is a subclass of Num, it can be used without problems in a division, but then the constraint will become
stronger and be for class Fractional:
Prelude> :t 3 * 20 / 4
3 * 20 / 4 :: Fractional a => a
The big difference is the identifier c is an Integer. The reason why a simple let-binding in GHCi prompt isn't assigned an overloaded type is the dreaded monomorphism restriction. In short: if you define a value that doesn't have any explicit arguments,
then it cannot have overloaded type unless you provide an explicit type signature.
Numeric types are then defaulted to Integer.
Once c is an Integer, the result of the multiplication is Integer, too:
Prelude> :t 3 * c
3 * c :: Integer
And Integer is not in the Fractional class.
There are two solutions to this problem.
Make sure your identifiers have overloaded type, too. In this case, it would
be as simple as saying
Prelude> let c :: Num a => a; c = 20
Prelude> :t c
c :: Num a => a
Use fromIntegral to cast an integral value to an arbitrary numeric value:
Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
Prelude> let c = 20
Prelude> :t c
c :: Integer
Prelude> :t fromIntegral c
fromIntegral c :: Num b => b
Prelude> 3 * fromIntegral c / 4
15.0
Haskell will never automatically convert one type into another when you pass it to a function. Either it's compatible with the expected type already, in which case no coercion is necessary, or the program fails to compile.
If you write a whole program and compile it, things generally "just work" without you having to think too much about int/float types; so long as you're consistent (i.e. you don't try to treat something as an Int in one place and a Float in another) the constraints just flow through the program and figure out the types for you.
For example, if I put this in a source file and compile it:
main = do
let c = 20
let it = 3 * c / 4
print it
Then everything's fine, and running the program prints 15.0. You can see from the .0 that GHC successfully figured out that c must be some kind of fractional number, and made everything work, without me having to give any explicit type signatures.
c can't be an integer because the / operator is for mathematical division, which isn't defined on integers. The operation of integer division is represented by the div function (usable in operator fashion as x `div` y). I think this might be what is tripping you up in your whole program? This is unfortunately just one of those things you have to learn by getting tripped up by it, if you're used to the situation in many other languages where / is sometimes mathematical division and sometimes integer division.
It's when you're playing around in the interpreter that things get messy, because there you tend to bind values with no context whatsoever. In interpreter GHCi has to execute let c = 20 on its own, because you haven't entered 3 * c / 4 yet. It has no way of knowing whether you intend that 20 to be an Int, Integer, Float, Double, Rational, etc
Haskell will pick a default type for numeric values; otherwise if you never use any functions that only work on one particular type of number you'd always get an error about ambiguous type variables. This normally works fine, because these default rules are applied while reading the whole module and so take into account all the other constraints on the type (like whether you've ever used it with /). But here there are no other constraints it can see, so the type defaulting picks the first cab off the rank and makes c an Integer.
Then, when you ask GHCi to evaluate 3 * c / 4, it's too late. c is an Integer, so must 3 * c be, and Integers don't support /.
So in the interpreter, yes, sometimes if you don't give an explicit type to a let binding GHC will pick an incorrect type, especially with numeric types. After that, you're stuck with whatever operations are supported by the concrete type GHCi picked, but when you get this kind of error you can always rebind the variable; e.g. let c = 20.0.
However I suspect in your real program the problem is simply that the operation you wanted was actually div rather than /.
Haskell is a bit unusual in this way. Yes you can't divide to integers together but it's rarely a problem.
The reason is that if you look at the Num typeclass, there's a function fromIntegral this allows you to convert literals into the appropriate type. This with type inference alleviates 99% of the cases where it'd be a problem. Quick example:
newtype Foo = Foo Integer
deriving (Show, Eq)
instance Num Foo where
fromInteger _ = Foo 0
negate = undefined
abs = undefined
(+) = undefined
(-) = undefined
(*) = undefined
signum = undefined
Now if we load this into GHCi
*> 0 :: Foo
Foo 0
*> 1 :: Foo
Foo 0
So you see we are able to do some pretty cool things with how GHCi parses a raw integer. This has a lot of practical uses in DSL's that we won't talk about here.
Next question was how to get from a Double to an Integer or vice versa. There's a function for that.
In the case of going from an Integer to a Double, we'd use fromInteger as well. Why?
Well the type signature for it is
(Num a) => Integer -> a
and since we can use (+) with Doubles we know they're a Num instance. And from there it's easy.
*> 0 :: Double
0.0
Last piece of the puzzle is Double -> Integer. Well a brief search on Hoogle shows
truncate
floor
round
-- etc ...
I'll leave that to you to search.
Type coercion in Haskell isn't automatic (or rather, it doesn't actually exist). When you write the literal 20 it's inferred to be of type Num a => a (conceptually anyway. I don't think it works quite like that) and will, depending on the context in which it is used (i.e. what functions you pass it to) be instantiated with an appropitiate type (I believe if no further constraints are applied, this will default to Integer when you need a concrete type at some point). If you need a different kind of Num, you need to convert the numbers e.g. (3* fromIntegral c / 4) in your example.
The type of (/) is Fractional a => a -> a -> a.
To divide Integers, use div instead of (/). Note that the type of div is
div :: Integral a => a -> a -> a
In most top-level languages the compiler works for me -- not the other way around.
I argue that the Haskell compiler works for you just as much, if not more so, than those of other languages you have used. Haskell is a very different language than the traditional imperative languages (such as C, C++, Java, etc.) you are probably used to. This means that the compiler works differently as well.
As others have stated, Haskell will never automatically coerce from one type to another. If you have an Integer which needs to be used as a Float, you need to do the conversion explicitly with fromInteger.

Haskell types frustrating a simple 'average' function

I'm playing around with beginner Haskell, and I wanted to write an average function. It seemed like the simplest thing in the world, right?
Wrong.
It seems like Haskell's type system forbids average from working on a generic numeric type - I can get it to work on a list of Integrals, or an list of Fractionals, but not both.
I want:
average :: (Num a, Fractional b) => [a] -> b
average xs = ...
But I can only get:
averageInt :: (Integral a, Fractional b) => [a] -> b
averageInt xs = fromIntegral (sum xs) / fromIntegral (length xs)
or
averageFrac :: (Fractional a) => [a] -> a
averageFrac xs = sum xs / fromIntegral (length xs)
and the second one seems to work. Until I try to pass a variable.
*Main> averageFrac [1,2,3]
2.0
*Main> let x = [1,2,3]
*Main> :t x
x :: [Integer]
*Main> averageFrac x
<interactive>:1:0:
No instance for (Fractional Integer)
arising from a use of `averageFrac ' at <interactive>:1:0-8
Possible fix: add an instance declaration for (Fractional Integer)
In the expression: average x
In the definition of `it': it = averageFrac x
Apparently, Haskell is really picky about its types. That makes sense. But not when they could both be [Num]
Am I missing an obvious application of RealFrac?
Is there way to coerce Integrals into Fractionals that doesn't choke when it gets a Fractional input?
Is there some way to use Either and either to make some sort of polymorphic average function that would work on any sort of numeric array?
Does Haskell's type system outright forbid this function from ever existing?
Learning Haskell is like learning Calculus. It's really complicated and based on mountains of theory, and sometimes the problem is so mindbogglingly complex that I don't even know enough to phrase the question correctly, so any insight will be warmly accepted.
(Also, footnote: this is based off a homework problem. Everybody agrees that averageFrac, above, gets full points, but I have a sneaking suspicion that there is a way to make it work on both Integral AND Fractional arrays)
So fundamentally, you're constrained by the type of (/):
(/) :: (Fractional a) => a -> a -> a
BTW, you also want Data.List.genericLength
genericLength :: (Num i) => [b] -> i
So how about removing the fromIntegral for something more general:
import Data.List
average xs = realToFrac (sum xs) / genericLength xs
which has only a Real constraint (Int, Integer, Float, Double)...
average :: (Real a, Fractional b) => [a] -> b
So that'll take any Real into any Fractional.
And note all the posters getting caught by the polymorphic numeric literals in Haskell. 1 is not an integer, it is any number.
The Real class provides only one method: the ability to turn a value in class Num to a rational. Which is exactly what we need here.
And thus,
Prelude> average ([1 .. 10] :: [Double])
5.5
Prelude> average ([1 .. 10] :: [Int])
5.5
Prelude> average ([1 .. 10] :: [Float])
5.5
Prelude> average ([1 .. 10] :: [Data.Word.Word8])
5.5
The question has been very well answered by Dons, I thought I might add something.
When calculating the average this way :
average xs = realToFrac (sum xs) / genericLength xs
What your code will do is to traverse the list twice, once to calculate the sum of its elements, and once to get its length.
As far as I know, GHC isn't able yet to optimize this and compute both the sum and length in a single pass.
It doesn't hurt even as a beginner to think about it and about possible solutions, for example the average function might be written using a fold that computes both the sum and length; on ghci :
:set -XBangPatterns
import Data.List
let avg l=let (t,n) = foldl' (\(!b,!c) a -> (a+b,c+1)) (0,0) l in realToFrac(t)/realToFrac(n)
avg ([1,2,3,4]::[Int])
2.5
avg ([1,2,3,4]::[Double])
2.5
The function doesn't look as elegant, but the performance is better.
More information on Dons blog:
http://donsbot.wordpress.com/2008/06/04/haskell-as-fast-as-c-working-at-a-high-altitude-for-low-level-performance/
Since dons has done such a good job at answering your question, I'll work on questioning your question....
For example, in your question, where you first run an average on a given list, getting a good answer. Then, you take what looks like the exact same list, assign it to a variable, then use the function the variable...which then blows up.
What you've run into here is a set-up in the compiler, called the DMR: the D readed M onomorphic R estriction. When you passed the list straight into the function, the compiler made no assumption about which type the numbers were, it just inferred what types it could be based on usage, and then picked one once it couldn't narrow the field down any more. It's kind of like the direct opposite of duck-typing, there.
Anyway, when you assigned the list to a variable, the DMR kicked in. Since you've put the list in a variable, but given no hints on how you want to use it, the DMR made the compiler pick a type, in this case, it picked one that matched the form and seemed to fit: Integer. Since your function couldn't use an Integer in its / operation (it needs a type in the Fractional class), it makes that very complaint: there's no instance of Integer in the Fractional class. There are options you can set in GHC so that it doesn't force your values into a single form ("mono-morphic", get it?) until it needs to, but it makes any error messages slightly tougher to figure out.
Now, on another note, you had a reply to dons' answer that caught my eye:
I was mislead by the chart on the last page of cs.ut.ee/~varmo/MFP2004/PreludeTour.pdf
that shows Floating NOT inheriting properties from Real, and I then assumed that
they would share no types in common.
Haskell does types differently from what you're used to. Real and Floating are type classes, which work more like interfaces than object classes. They tell you what you can do with a type that's in that class, but it doesn't mean that some type can't do other things, any more than having one interface means that a(n OO-style) class can't have any others.
Learning Haskell is like learning Calculus
I'd say learning Haskell is like learning Swedish - there are lots of little, simple things (letters, numbers) that look and work the same, but there are also words that look like they should mean one thing, when they actually mean something else. But once you get fluent in it, your regular friends will be amazed at how you can spout off this oddball stuff that makes gorgeous beauties do amazing tricks. Curiously, there are many folks involved in Haskell from the beginnings, who also know Swedish. Maybe that metaphor is more than just a metaphor...
:m Data.List
let list = [1..10]
let average = div (sum list) (genericLength list)
average
I'm amazed that after all of these years, no one has pointed out that Don Stewart's average doesn't work with complex numbers, while OP's averageFrac does work with complex numbers. Neither one is unambiguously superior to the other.
The fundamental reason why you can't write
average :: (Num a, Fractional b) => [a] -> b
is that it can be instantiated at a type like
average :: [Complex Double] -> Double
Haskell's numeric classes support conversions that are a little bit lossy, like Rational to Double, Double to Float, and Integer to Int, but don't support extremely lossy conversions like complex to real, or fractional to integral. You can't convert Complex Double to Double without explicitly taking (e.g.) the real part of it, which is not something that average should be doing. Therefore, you can't write average :: [Complex Double] -> Double. Therefore, you can't write average with any type that can be specialized to [Complex Double] -> Double.
The most Haskellish type for average is probably OP's averageFrac. Generally, functions that aren't dedicated to type conversion should be leaving the type conversion to the caller as much as possible. averageFrac will work with practically any numeric type, either directly or after coercion of the input list. The caller, being closer to the source of the data, is more likely to know whether it needs to be coerced or not (and if it doesn't know, it can leave the decision to its caller). In contrast, Don Stewart's average just doesn't support complex numbers, even with coercion. You'd either have to rewrite it from scratch or else call it twice with the real and imaginary projections of the list (and then write another wrapper for quaternions that calls it four times, etc.).
Yeah, Haskell's type system is very picky. The problem here is the type of fromIntegral:
Prelude> :t fromIntegral
fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral will only accept an Integral as a, not any other kind of Num. (/), on the other hand only accepts fractional. How do you go about making the two work together?
Well, the sum function is a good start:
Prelude> :t sum
sum :: (Num a) => [a] -> a
Sum takes a list of any Num and returns a Num.
Your next problem is the length of the list. The length is an Int:
Prelude> :t length
length :: [a] -> Int
You need to convert that Int into a Num as well. That's what fromIntegral does.
So now you've got a function that returns a Num and another function that returns a Num. There are some rules for type promotion of numbers you can look up, but basically at this point you're good to go:
Prelude> let average xs = (sum xs) / (fromIntegral (length xs))
Prelude> :t average
average :: (Fractional a) => [a] -> a
Let's give it a trial run:
Prelude> average [1,2,3,4,5]
3.0
Prelude> average [1.2,3.4,5.6,7.8,9.0]
5.4
Prelude> average [1.2,3,4.5,6,7.8,9]
5.25

Resources