A list comprehension with double elements [duplicate] - haskell

I know that floats can lead to odd behavior in ranges due to their imprecise nature.
I would expect the possibility of imprecise values. For instance:
[0.1,0.3..1] might give [0.1,0.3,0.5,0.7,0.8999999999999999] instead of [0.1,0.3,0.5,0.7,0.9]
In addition to the precision loss, however, I get an extra element:
ghci> [0.1,0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
This is weird, but explained here. I could work around it like this, I suppose:
ghci> [0.1,0.3..0.99]
[0.1,0.3,0.5,0.7,0.8999999999999999]
But that's kind of gross. Maybe there's a cleaner way. For this simple example, of course, I could just use the range [0.1,0.3..0.9] and everything is fine.
But in a more complex example, I may not quickly know (or care to figure out, if I'm lazy) the exact upper bound I should use. So, I'll just make a range of integers and then divide by 10, right? Nope:
ghci> map (/10) [1,3..10]
[0.1,0.3,0.5,0.7,0.9,1.1]
Any floating point function seems to cause this behavior:
ghci> map (*1.0) [1,3..10]
[1.0,3.0,5.0,7.0,9.0,11.0]
Whereas a non-floating function doesn't:
ghci> map (*1) [1,3..10]
[1,3,5,7,9]
While it seems unlikely, I thought that maybe some lazy evaluation was at play, and tried to force evaluation of the range first:
ghci> let list = [1,3..10] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0,11.0]
Obviously, using the literal list instead of the range works fine:
ghci> map (*1.0) [1,3,5,7,9]
[1.0,3.0,5.0,7.0,9.0]
ghci> let list = [1,3,5,7,9] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0]
It isn't just mapping either:
ghci> last [1,3..10]
9
ghci> 1.0 * (last [1,3..10])
11.0
How does applying a function to the result of a range can impact the actual evaluated result of that range?

I answered this for myself as I was writing it.
Haskell uses type inference, so when it sees a floating point function being mapped over a list (or used on an element of that list, as in my example using last), it is going to infer the type of that list to be floating point and therefore evaluate the range as if it were [1,3..10] :: [Float] instead of what I was intending, which is [1,3..10] :: [Int]
At this point, it uses the Float rules for enumerating, as described in the post that I linked to in the question.
The expected behavior can be forced like this:
ghci> map (\x -> (fromIntegral x) / 10) ([1,3..10]::[Int])
[0.1,0.3,0.5,0.7,0.9]
Relying on Haskell's type inference, we can drop the ::[Int] since fromIntegral causes our lambda expression to have the correct type:
ghci> :t (\x -> (fromIntegral x) / 10)
(\x -> (fromIntegral x) / 10)
:: (Fractional a, Integral a1) => a1 -> a

Related

Why has Haskell decided against using `+` for string (list) concatenation?

Since I had trouble googling this question I thought I'd post it here.
I'm just interested in the logic behind it or wether it's just the creators' preference to use ++ instead. I mean, using a typeclass for strings that concatenates two strings (or rather lists) with + does not seem too hard to imagine.
Edit: I should add, that in Haskell one has to suspect reasons behind it, because + and ++ are functions defined in typeclasses, whereas in java the usage of + for string concatenation is just part of the language's syntax and therefor subject only to the creators preference/opinion. (The answers so far suggest that I was right about my suspicion.)
Also haskell comes from a mathematical background and is deeply influenced by mathematical syntax, so there might be deeper reasons than just preference/opinion.
typeclass for strings that concatenates two strings
Such a typeclass exists, although the operator isn't +, but <>:
Prelude> :m +Data.Monoid
Prelude Data.Monoid> "foo" <> "bar"
"foobar"
While ++ concatenates lists, the <> operator is more general, since it combines any two values of a given Monoid instance.
As other people have pointed out, + is reserved for Num instances. Why isn't the Monoid binary operator called +, then? Because addition is only one of infinitely many monoids; multiplication is another:
Prelude Data.Monoid> Sum 2 <> Sum 3
Sum {getSum = 5}
Prelude Data.Monoid> Product 2 <> Product 3
Product {getProduct = 6}
Choosing something like <> as 'the' monoidal operator is preferred exactly because it carries little semantic baggage.
Long story short, it would cause type troubles.
(+) is part of the Num typeclass:
class Num a where
(+), (-), (*) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
x - y = x + negate y
negate x = 0 - x
And (++) :: [a] -> [a] -> [a].
It's easy to see the first problem: if we wanted (+) to work on list, we would have to implement (*), negate, abs, signum, and fromInteger for lists as well. Which is spurious.
If we decided to seperate (+) from the typeclass, and make a new typeclass, maybe called Plussable for (+), there would be too many typeclasses to keep track of, and simple expressions like 1 + 2*(2-1) would no longer be of type Num a => a, it would be of type (Plussable a, Timesable a, Minusable a) => a, and so on for each operation. It would be far too complicated.

Why is the use of (>100) partial application?

This code illustrates the use of partial application through the use of an operator section :
gt100 :: Integer -> Bool
gt100 x = x > 100
greaterThan100 :: [Integer] -> [Integer]
greaterThan100 xs = filter gt100 xs
greaterThan100_2 :: [Integer] -> [Integer]
greaterThan100_2 xs = filter (\x -> x > 100) xs
greaterThan100_3 :: [Integer] -> [Integer]
greaterThan100_3 xs = filter (>100) xs
The operator section (>100) partially applies the operator to one
of its two arguments. So the operator in this case is >
Why is this partial application as the > operator is being applied
to the entire Integer list ?
How is this different from lambda expression (\x -> x > 100) which
apparently is not partial application ?
Taken from http://www.seas.upenn.edu/~cis194/spring13/lectures/04-higher-order.html
Update :
Thanks to answers this appears clearer.
So here now is my understanding :
*Main> :t (>)
(>) :: Ord a => a -> a -> Bool
Is not applied at all as it accepts two parameters "a -> a" but they are not applied.
*Main> :t (>100)
(>100) :: (Ord a, Num a) => a -> Bool
Is partially applied as a function of type "a -> Bool" is created
*Main> :t (3>100)
(3>100) :: Bool
Is evaluated to type Bool which is the return type of operator (>) as illustrated by :t (>)
Why is this partial application as the > operator is being applied to the entire Integer list ?
It is not applied to the entire list, as a whole, but to the individual elements, one by one. When the > is partially applied over 100, it creates a new function.
Prelude> :type (> 100)
(> 100) :: (Num a, Ord a) => a -> Bool
Now, the function accepts an argument and returns Bool. This function is applied to all the elements in the list by the filter function.
How is this different from lambda expression (\x -> x > 100) which apparently is not partial application ?
> is a function which needs two operands to operate. You are already passing one of them, as 100. To completely execute the function, you need one more argument. So, the function > is partially applied with 100.
In the second case, you are creating a new function which needs only one argument to execute. Once you pass that argument, your function will be executed. So, the lambda function is not applied partially.
How is this [(<) 100] different from lambda expression (\x -> (<) 100 x) which apparently is not partial application? [1]
I think it is important to draw a distinction between semantic properties and syntactic properties. The two terms you suggested are semantically identical -- that is, there is no Haskell function you can write that reduces to one thing when applied to (<) 100 and reduces to a different thing when applied to (\x -> (<) 100 x).
However, partial application is a syntactic property -- that is, it is a property not of the behavior of a term but of the particular implementation chosen. (In analogous terms to my definition of a semantic property, a syntactic property is about whether you could write a Haskell function that reduces to one thing when applied to the string "(<) 100" and reduces to a different thing when applied to the string "(\x -> (<) 100 x)", which is eminently possible.) If I had to define it, I would define it this way: partial application is an application term with an arrow type. [2] Both of your terms are well-typed and have arrow types. But (<) 100 is an application term, whereas \x -> (<) 100 x is a lambda term (that has an application in its body).
As for operator sections like (100<) and (>100), it is not immediately obvious what to do with these. One choice is to simply decree that all operator sections are partial applications (or to simply decree that no operator sections are partial applications, of course). Another is to treat them as shorthand for (<) 100 and flip (>) 100, respectively, in which case we would still consider them partial applications (since they are application terms and have arrow types). [3] Yet a third is to treat them as shorthand for \x -> (<) 100 x and \x -> (>) x 100, respectively, in which case one might claim they are not partial applications.
But the distinction is, in my opinion, not too important: generally, semantic properties are more interesting and useful than merely syntactic ones.
[1] To avoid muddying the waters, I have used (<) 100 instead of (>100). We will discuss this distinction shortly.
[2] There is some question about what to do if the type is polymorphic. Let's punt on that question for now.
[3] This differs from simply decreeing that all operator sections are partial applications; consider some one-argument operator (!) and its section (100!), which we would then be treating as shorthand for (!) 100. This is an application term, but does not have an arrow in its type.

Using Haskell ranges: Why would mapping a floating point function across a range cause it to return an extra element?

I know that floats can lead to odd behavior in ranges due to their imprecise nature.
I would expect the possibility of imprecise values. For instance:
[0.1,0.3..1] might give [0.1,0.3,0.5,0.7,0.8999999999999999] instead of [0.1,0.3,0.5,0.7,0.9]
In addition to the precision loss, however, I get an extra element:
ghci> [0.1,0.3..1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
This is weird, but explained here. I could work around it like this, I suppose:
ghci> [0.1,0.3..0.99]
[0.1,0.3,0.5,0.7,0.8999999999999999]
But that's kind of gross. Maybe there's a cleaner way. For this simple example, of course, I could just use the range [0.1,0.3..0.9] and everything is fine.
But in a more complex example, I may not quickly know (or care to figure out, if I'm lazy) the exact upper bound I should use. So, I'll just make a range of integers and then divide by 10, right? Nope:
ghci> map (/10) [1,3..10]
[0.1,0.3,0.5,0.7,0.9,1.1]
Any floating point function seems to cause this behavior:
ghci> map (*1.0) [1,3..10]
[1.0,3.0,5.0,7.0,9.0,11.0]
Whereas a non-floating function doesn't:
ghci> map (*1) [1,3..10]
[1,3,5,7,9]
While it seems unlikely, I thought that maybe some lazy evaluation was at play, and tried to force evaluation of the range first:
ghci> let list = [1,3..10] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0,11.0]
Obviously, using the literal list instead of the range works fine:
ghci> map (*1.0) [1,3,5,7,9]
[1.0,3.0,5.0,7.0,9.0]
ghci> let list = [1,3,5,7,9] in seq list (map (*1.0) list)
[1.0,3.0,5.0,7.0,9.0]
It isn't just mapping either:
ghci> last [1,3..10]
9
ghci> 1.0 * (last [1,3..10])
11.0
How does applying a function to the result of a range can impact the actual evaluated result of that range?
I answered this for myself as I was writing it.
Haskell uses type inference, so when it sees a floating point function being mapped over a list (or used on an element of that list, as in my example using last), it is going to infer the type of that list to be floating point and therefore evaluate the range as if it were [1,3..10] :: [Float] instead of what I was intending, which is [1,3..10] :: [Int]
At this point, it uses the Float rules for enumerating, as described in the post that I linked to in the question.
The expected behavior can be forced like this:
ghci> map (\x -> (fromIntegral x) / 10) ([1,3..10]::[Int])
[0.1,0.3,0.5,0.7,0.9]
Relying on Haskell's type inference, we can drop the ::[Int] since fromIntegral causes our lambda expression to have the correct type:
ghci> :t (\x -> (fromIntegral x) / 10)
(\x -> (fromIntegral x) / 10)
:: (Fractional a, Integral a1) => a1 -> a

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

Reliable cube root in Haskell

I am doing question 62 at project euler and came up with the following to test whether a number is cubic:
isInt x = x == fromInteger (round x)
isCube x= isInt $ x**(1/3)
But due to floating point error, it returns incorrect results:
*Main> isCube (384^3)
False
Is there a way to implement a more reliable cube test?
On a side-note, here is the rest of my solution, which doesn't work because of a type interface error on filter (isCube) (perms n):
cubes = [n^3|n<-[1..]]
perms n = map read $ permutations $ show n :: [Integer]
answer = head [n|n<-cubes,(length $ filter (isCube) (perms n)) == 5]
What do I need to do to fix the error?
No instances for (Floating Integer, RealFrac Integer)
arising from a use of `isCube' at prob62.hs:10:44-49
Any optimisations are also welcome ;-)
Try to avoid using floating point numbers as much as possible, especially when you have a problem which concerns integer values. Floating point numbers have problems with rounding and that certain values (like 1/3) cannot be represented exactly. So it's no surprise that you get mysterious answers.
First of all, in order to fix your type error you have to redefine isCube. If you check it's type signature it looks like this:
isCube :: (RealFrac a, Floating a) => a -> Bool
Note that it expects something that is of class Floating as its first argument. Your problem is that you want to use this function on integer values and integers are not an instance of Floating. You can redefine isCube like this to make the function type check.
isCube x = isInt $ (fromIntegral x) ** (1/3)
However, that will not make your program correct.
One way to make your program more correct is to do what Henrik suggested. It would look like this:
isCube x = (round (fromIntegral x ** (1/3))) ^ 3 == x
Good luck!
Don't know much about Haskell, but I would take the cube root, round to the nearerst integer, take the cube, and compare to the original value.
For another approach useful for Integer values have a look at the integerCubeRoot function in the arithmoi package.
Example:
ghci> import Math.NumberTheory.Powers.Cube
ghci> let x = 12345^3333
ghci> length $ show x
13637
ghci> isCube x
True
ghci> isCube (x+1)
False
ghci> length $ show $ integerCubeRoot x
4546
perms has the type [Integer]. isCube has the type (RealFrac a, Floating a) => a -> Bool (as you can check in GHCI). The RealFrac constraint comes from round x, the Floating constraint comes from x**(1/3). Since Integer is neither RealFrac nor Floating, isCube can't be used as Integer -> Bool. So filter isCube (perms n) doesn't make sense.
So you need to fix isCube to work properly on Integers:
isCube x = isInt $ (fromInteger x)**(1/3)
In fact, the reason isCube (384^3) even compiles is that it "really" means isCube ((fromInteger 384)^(fromInteger 3)).
Of course, this will still work badly due to floating point errors. Basically, checking floating numbers for equality, as you do in isInt, is almost always a bad idea. See other answers for explanation how to make a better test.

Resources