Reputation: 2112
I've just started playing with GHCi. I see that list generators basically solve an equation within a given set:
Prelude> [x | x <- [1..20], x^2 == 4]
[2]
(finds only one root, as expected)
Now, why can't I solve equations with results in ℝ, given that the solution is included in the specified range?
[x | x <- [0.1,0.2..2.0], x*4 == 2]
How can I solve such equations within real numbers set?
Edit: Sorry, I meant 0.1
, of course.
Upvotes: 2
Views: 2155
Reputation: 370212
First of all [0.01,0.2..2.0]
wouldn't include 0.5 even if floating point arithmetic were accurate. I assume you meant the first element to be 0.1
.
The list [0.1,0.2..2.0]
does not contain 0.5 because floating point arithmetic is imprecise and the 5th element of [0.1,0.2..2.0]
is 0.5000000000000001
, not 0.5.
Upvotes: 3
Reputation: 53695
As others have mentioned, this is not an efficient way to solve equations, but it can be done with ratios.
Prelude> :m +Data.Ratio
Prelude Data.Ratio> [x|x<-[1%10, 2%10..2], x*4 == 2]
[1 % 2]
Read x % y
as x divided by y
.
Upvotes: 5
Reputation: 5914
The floating point issue can be solved in this way:
Prelude> [x | x <- [0.1, 0.2 .. 2.0], abs(2 - x*4) < 1e-9]
[0.5000000000000001]
For a reference why floating point numbers can make problems see this: Comparing floating point numbers
Upvotes: 4
Reputation: 26060
List comprehension doesn't solve equations, it just generates a list of items that belong to certain sets. If your set is defined as any x
in [1..20]
such that x^2==4
, that's what you get.
You cannot do that with a complete list of any real number from 0.01
to 2.0
, because such real list cannot be represented in haskell (or better: it cannot be represented on any computer), since it has infinite numbers with infinite precision.
[0.01,0.2..2.0]
is a list made of the following numbers:
Prelude> [0.01,0.2..2.0]
[1.0e-2,0.2,0.39,0.5800000000000001,0.7700000000000001,0.9600000000000002,1.1500000000000004,1.3400000000000005,1.5300000000000007,1.7200000000000009,1.910000000000001]
And none of these numbers satisfies your condution.
Note that you probably meant [0.1,0.2..2.0]
instead of [0.01,0.2..2.0]
. Still:
Prelude> [0.1,0.2..2.0]
[0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0,1.1,1.2000000000000002,1.3000000000000003,1.4000000000000004,1.5000000000000004,1.6000000000000005,1.7000000000000006,1.8000000000000007,1.9000000000000008,2.000000000000001]
Upvotes: 8