Is there a general way to prevent overflows when summing lists? - haskell

I'm working with ByteStrings, and by extension a lot of Word8.
When i write sum word8List, the returned value is also Word8, but i know my data, and that sum is too large for a Word8. Should i avoid sum, or does it work differently than i think?
Is there some general function for summing numbers without overflowing, like Num a => a -> Integer?

The sum will use the (+) defined for that type, so for a Word8, it will make a wraparound.
You can however first perform a mapping, for example with fromIntegral :: (Integral a, Num b) => a -> b, and thus convert the numbers to another numeric type (like Integer, Word16, Word32, etc.). For example:
sum (map fromIntegral word8List) :: Integer

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.

In Haskell, is there a good way to write a num to num conversion function `toNum :: (Num a, Num b) => a -> b`?

For example, one bad way is to factor through a string:
toReadableNum :: (Num a, Num b, Read b) => a -> b
toReadableNum = read . show
If there are no good ways, are there other bad ways? Implementation specific? Requiring language extension?
You can't go (sanely) from Num to Num, as Num provides no mechanism for extracting information about the value held other than its spurious Eq and Show machinery, but if you are willing to assume a bit more on the behalf of the number you are coming from, then you can have recourse.
In particular
fromIntegral :: (Integral a, Num b) => a -> b
and the composition of
toRational :: Real a => a -> Rational
with
fromRational :: Fractional a => Rational -> a
are both good candidates for doing what you mean, if not exactly what you asked for.
While read . show is well typed and has the signature you propose, the meaning is gobbledigook. There is nothing at all that says the text emitted by one Show instance will be compatible with a completely different Read instance, and there are plenty of counter examples.
The (implied) contract on Read and Show only apply when you use them with the same type!
There are no good ways. Some numbers contain more information that other, so how could you expect to convert between two arbitrary numbers in a good way. Some simple examples: How do you convert a Double to an Int? A Rational to on Int8? A Complex Double to a Float?
All this involve information loss and then there is no obvious right way.
And as #hammar says, the operations in Num simply don't allow you to construct such a function.
You cannot write any useful function of the type (Num a, Num b) => a -> b. Since a and b are type variables, the only useful operations we can use on them are the ones in the Num class. (Eq and Show won't help us much here).
class (Eq a, Show a) => Num a where
(+), (-), (*) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
The only function here that allows you to make an b if you didn't have one to start with is fromInteger, but you have no way of turning a into an Integer, so the only functions you can write of this type return fromInteger of some constant, or bottom. Not very useful.
As augustss pointed out, there is no obvious way of making this conversion anyway. Remember lots of types can be Num. Not only the various types of real numbers, but also complex numbers, matrices, polynomials, etc. There is no meaningful conversion that would work between all of them.
The good way is to make specific kind of conversion, like round or clamp. Such function does what it say it does.

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

Haskell: Constrain function on type Double to only work with Integers

Suppose I'm writing a function that takes a list of integers and returns only those integers in the list that are less than 5.2. I might do something like this:
belowThreshold = filter (< 5.2)
Easy enough, right? But now I want to constrain this function to only work with input lists of type [Int] for design reasons of my own. This seems like a reasonable request. Alas, no. A declaration that constraints the types as so:
belowThreshold :: [Integer] -> [Integer]
belowThreshold = filter (< 5.2)
Causes a type error. So what's the story here? Why does doing filter (< 5.2) seem to convert my input list into Doubles? How can I make a version of this function that only accepts integer lists and only returns integer lists? Why does the type system hate me?
Check the inferred type of belowThreshold in ghci before adding your annoatation:
> :t belowThreshold
belowThreshold :: [Double] -> [Double]
It sounds like you expected Num a => [a] -> [a] when you said "constrain this function". You are actually changing the type of the function when you add the [Integer] -> [Integer] annotation.
To make this work, use an explicit conversion:
belowThreshold = filter ((< 5.2) . fromIntegral)
Now belowThreshold :: [Integer] -> [Integer] like you wanted. But the integers are converted to doubles before comparison to 5.2.
So why do you need the conversion? The type error probably misled you: the list of Integers wasn't being converted to Doubles by comparison to 5.2, the real problem is that only Doubles can be compared to Doubles, so you must pass a list of Doubles to belowThreshold. Haskell has no implicit conversions, not even between numbers. If you want conversions, you have to write them yourself.
I want to constrain this function to only work with input lists of type [Int] for design reasons of my own. This seems like a reasonable request.
Well, from the perspective of the type system, no. Is this reasonable code?
'c' < "foo"
What about this?
12 < "bar"
All of these values are instances of Ord, but you can't use them together with (<). Haskell has no implicit conversions. So even if two values are both instances of Num as well as Ord, you won't be able to compare them with (<) if they are of different types.
You are trying to compare an Integer to a double (5.2). Haskell doesn't like that. Try using
filter (< 6)
If you must use a double (let's say it is an argument), I would use ceiling:
filter (< (ceiling 5.2))
Now if you want a function that takes in the bounding value as 'any' (relevant) numeric value, you can make your own type class to ceiling the number for you.
class Ceilingable a where
ceil :: (Integral b) => a -> b
instance (RealFrac a) => Ceilingable a where
ceil = ceiling
instance (Integral a) => Ceilingable a where
ceil = fromIntegral
belowThreshold :: (Ceilingable a) => a -> [Integer] -> [Integer]
belowThreshold threshold = filter (< ceil threshold)
The syntax 5.2 is valid for any Fractional. Int is not an instance of Fractional, nor can or should it be. As what to do when converting an arbitrary Rational to an Int is underspecified.
The conversion to a Double from an arbitrary fraction, however makes perfectly good sense (within the range of the type).
Your expectation is driven by the presence of implicit coercions in many languages.
However, those come with a cost. You have to manually ensure that the entire system of coercions is confluent. Haskell does not do this, choosing instead to let numeric literal syntax leverage the type system. To convert between them you need to use fromIntegral to make explicit the need for coercion, this avoids relying on confluence and allows programmers to define new numeric types.
belowThreshold = filter (\x -> fromIntegral x < 5.2)
This is analogous to using an explicit conversion in C++, like ((double)x < 5.2). Although, this statement only works because of defaulting, because 5.2 could be used as a member of any Fractional, and the result of 'fromIntegral x' is any Num, a superclass of Fractional, so fromIntegral x < 5.2 is underspecified, it merely knows that it needs to compare two Fractional values of the same type and it chooses Double as a reasonable default, based on a 'default' statement.
Also note that Int is not the only Integral type, so the above method works on any list of Integral values:
belowThreshold :: Integral a => [a] -> [a]

Haskell Error: Couldn't match expected type `Integer' against inferred type `Int'

I have a haskell function that that calculates the size of the list of finite Ints. I need the output type to be an Integer because the value will actually be larger than the maximum bound of Int (the result will be -1 to be exact if the output type is an Int)
size :: a -> Integer
size a = (maxBound::Int) - (minBound::Int)
I understand the difference between Ints (bounded) and Integers (unbounded) but I'd like to make an Integer from an Int. I was wondering if there was a function like fromInteger, that will allow me to convert an Int to an Integer type.
You'll need to convert the values to Integers, which can be done by the fromIntegral function (numeric casting for Haskell):
fromIntegral :: (Integral a, Num b) => a -> b
It converts any type in the Integral class to any type in the (larger) Num class. E.g.
fromIntegral (maxBound::Int) - fromIntegral (minBound::Int)
However, I would not really trust the approach you're taking -- it seems very fragile. The behaviour in the presence of types that admit wraparound is pretty suspect.
What do you really mean by: "the size of the list of finite Ints". What is the size in this sense, if it isn't the length of the list?
I believe you are looking for:
fromIntegral :: (Integral a, Num b) => a -> b
which will convert an Integer to an Int
Perhaps you were assuming that Haskell, like many main-stream languages like C and (to a certain extent) Java, has implicit numeric coercions. It doesn't: Int and Integer are totally unrelated types and there is a special function for converting between them: fromIntegral. It belongs to the Num typeclass. Look at the documentation: essentially, fromIntegral does more than that: it is a generic "construct the representation of an arbitrary integral number", t.i. if you're implementing some kind of numbers and instantiating Num, you must provide a way to construct integral numbers of your type. For example, in the Num instance for complex numbers, fromIntegral creates a complex number with a zero imaginary part and an integral real part.
The only sense in which Haskell has implicit numeric coercions is that integer literals are overloaded, and when you write 42, the compiler implicitly interprets it as "fromIntegral (42::Integer)", so you can use integers in whatever contexts where a Num type is required.

Resources