NewDev90
NewDev90

Reputation: 399

Type Error F# "The type "int" does not match...."

I am currently working on a simple program, that returns two points (int * int), of the smallest rectangle containing two figures (a circle and another rectangle, defined as box and circ which can be seen below). My program thus far, is this:

type point = int * int // a point (x, y) in the plane
type colour = int * int * int // (red , green , blue ), 0..255
type name = string

type figure =
    | Circle of point * int * colour
    // defined by center , radius , and colour
    | Rectangle of point * point * colour
    // defined by corners bottom -left , top -right , and colour
    | Mix of figure * figure
    // combine figures with mixed colour at overlap

// finds colour of figure at point
let rec colourAt (x ,y) figure =
    match figure with
    | Circle ((cx, cy), r, col) ->
        if (x-cx)*(x-cx)+(y-cy)*(y-cy) <= r*r
        // uses Pythagoras ' equation to determine
        // distance to centers
        then Some col else None
    | Rectangle ((x0,y0), (x1,y1), col) ->
        if x0 <= x && x <= x1 && y0 <= y && y <= y1
        // within corners
        then Some col else None
    | Mix (f1,f2) ->
        match ( colourAt (x , y) f1 , colourAt (x ,y ) f2 ) with
        | (None, c) -> c // no overlap
        | (c, None ) -> c // no overlap
        | (Some (r1,g1,b1), Some (r2,g2,b2)) ->
        // average color
            Some ((r1+r2)/2, (g1+g2)/2, (b1+b2)/2)

(all above is predefined for the program, my code can be seem below) (please do not mind the types such as colour, col etc. which is used in other sub parts of the program, that allready works like a charm)

let box = Rectangle ((40,40),(90,110),(0,0,255))
let circ = Circle ((50,50),45,(255,0,0))
let figTest = Mix(box,circ)

let rec boundingBox figure : point * point =
    match figure with
    | Circle ((cx,cy), r, col) -> (point(cx-r,cy-r),point(cx+r,cy+r))
    | Rectangle ((x0,y0), (x1,y1), col) -> (point(x0,y0),point(x1,y1))
    | Mix(f1,f2) ->
        let (p1,p2) = boundingBox(f1)
        let (p3,p4) = boundingBox(f2)
        let p5 = (min((fst p1),(fst p3)),min((snd p1),(snd p3)))
        let p6 = (max((fst p2),(fst p4)),max((snd p2),(snd p4)))
        p5,p6 

printfn "Mix figTest --> %A" (boundingBox figTest)
printfn "Rectangle box --> %A" (boundingBox box) 
printfn "Circle circ --> %A" (boundingBox circ)

My problem with my program however is that my p5,p6 return values from the pattern matching on Mix(f1,f2) keeps giving me a Type error saying:

The type "int" does not match the type int * int -> int * int

I am pretty confident the code otherwise should be correct for the desired function.

However my program is expected to yield a point * point (where point = int * int). Can anyone see what I am missing? I can run my program on box and circle, which yields the correct results:

for circ = (5,5) (95,95) for box = (40,40) (90,110)

My last figTest which contains exactly (circ,box) should hence return min(5,40),min(40,5) = (5,5) and max(90,95),max(95,110) = (95,110) which together adds up to (5,5) (95,110) which is my expected result for Mix(f1,f2), but can't be read due to the Type Error described above.

What am I missing? I'm struggling alot with the type errors in my F# coding generally (which just seems to be a part of the learning by doing in F#), but I all ways seem to be able to fix it some how, but this one just wont give in no matter what I try.

Thanks in regards.

Upvotes: 1

Views: 2063

Answers (1)

AMieres
AMieres

Reputation: 5004

The problem is the parenthesis:

(min((fst p1),(fst p3))

should be:

(min (fst p1) (fst p3))

This should be your code:

let p5 = min (fst p1) (fst p3) , min (snd p1) (snd p3) 
let p6 = max (fst p2) (fst p4) , max (snd p2) (snd p4)

Most .Net functions that come from C# receive multiple parameters as tuples but min and max like most F# functions receive parameters separated by spaces not commas. You can see the difference in the signature: min: 'T -> 'T -> 'T which would be equivalent to

min: int -> int -> int

For a tuple it would be:

minT: int * int -> int

Upvotes: 1

Related Questions