Reputation: 133
I've another issue with my Haskell. I'm given the following data constructor from a problem,
type Point = (Int, Int)
data Points = Lines Int Int
| Columns Int Int
| Union Points Points
| Intersection Points Points
It's about points on a grid starting (0,0) and (x,y) has x as the horizontal distance from the origin and y as the vertical distance from the origin.
I tried to define a function "Lines" from this, which, given Lines x y would evaluate all points with vertical distance x ~ y on the grid. e.g.
> Lines 2 4
(0,2)(1,2)(2,2)(3,2)....
(0,3)(1,3)(2,3)(3,3)....
(0,4)(1,4)(2,4)(3,4)....
and so on. Well what I did, was,
Lines :: Int -> Int -> Points
Lines lo hi = [ (_, y) | lo <= y && y <= hi ]
But Haskell complains that;
Invalid type signature Lines :: Int -> Int -> Points.
Should be of the form ::
what's this mean? "Points" is defined above already...surely "Int" "Points" are regarded as "types"? I don't see the problem, why is Haskell confused?
Upvotes: 1
Views: 1521
Reputation: 62848
Functions must not start with a capital letter. So you need to use lines
, not Lines
. This is probably the source of the error message you're seeing.
The syntax [ ... ]
is for creating a list of results, but your type signature claims that the function returns Points
, which isn't any kind of list. If you meant to return a list of Point
values, that's the [Point]
type.
I have literally no idea what your implementation of Lines
is even trying to do. The syntax makes no sense to me.
OK, so taking your comments into account...
You can generate a list of numbers between lo
and hi
by writing [lo .. hi]
.
You say an "arbitrary" value can go in X, but you need to pin down exactly what that means. Your example seems to suggest you want the numbers from 0 upwards, forever. The way to generate that list is [0 .. ]
. (Not giving an upper limit makes the list endless.)
Your example suggests you want a list of lists, with the inner list containing all points with the same Y-coordinate paired with all possible X-coordinates.
So here is one possible way to do that:
type Point = (Int, Int)
lines :: Int -> Int -> [[Point]]
lines lo hi = [ [(x,y) | x <- [0..]] | y <- [lo .. hi] ]
That's perhaps a teeny bit hard to read, with all those opening and closing brackets, so perhaps I can make it slightly cleaner:
lines lo hi =
let
xs = [0..]
ys = [lo .. hi]
in [ [(x,y) | x <- xs] | y <- ys]
If you run this, you get
> lines 2 4
[[(0,2), (1,2), (2,2), ...],
[(0,3), (1,3), (2,3), ...],
[(0,4), (1,4), (2,4), ...]]
In other words, the outer list has 3 elements (Y=2, Y=3 and Y=4), and each of the three inner lists is infinitely long (every possible positive X value).
Upvotes: 9