Ошибка типа F # "Тип" int "не соответствует ...." - PullRequest
0 голосов
/ 26 ноября 2018

В настоящее время я работаю над простой программой, которая возвращает две точки (int * int) наименьшего прямоугольника, содержащего две фигуры (круг и еще один прямоугольник, определенные как прямоугольник и круг, которые можно увидеть ниже).Моя программа на данный момент такова:

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)

(все вышеперечисленное предопределено для программы, мой код может быть показан ниже) (пожалуйста, не обращайте внимания на такие типы, как color, col и т. Д., Которые используютсяв других подразделах программы, которые уже работают как шарм)

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)

Однако моя проблема с моей программой заключается в том, что мои значения p5, p6, возвращаемые из сопоставления с образцом в Mix (f1, f2), сохраняютсявыдает мне сообщение об ошибке типа:

Тип "int" не соответствует типу int * int -> int * int

Я вполне уверен, что код должен быть правильным для желаемогоfunction.

Однако моя программа должна выдавать точку * point (где point = int * int).Кто-нибудь может увидеть, что мне не хватает?Я могу запустить свою программу на коробке и круге, что дает правильные результаты:

для circ = (5,5) (95,95) для box = (40,40) (90,110)

Мой последний figTest, который содержит точно (кружок, прямоугольник), должен поэтому возвращать min (5,40), min (40,5) = (5,5) и max (90,95), max (95,110) = (95,110)) который вместе складывается из (5,5) (95,110), что является моим ожидаемым результатом для Mix (f1, f2), но не может быть прочитано из-за ошибки типа, описанной выше.

Что яотсутствует?Я много борюсь с ошибками типов в моем F #-кодировании в целом (что, кажется, является частью обучения через F #), но я, кажется, все способы как-то исправить, но этот просто неотдай, что бы я ни пытался.

Спасибо за привет.

1 Ответ

0 голосов
/ 26 ноября 2018

Проблема в скобках:

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

должно быть:

(min (fst p1) (fst p3))

Это должен быть ваш код:

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

Большинство .Net функцийполучаемые из C# получают несколько параметров в виде кортежей, но min и max, как и большинство функций F#, получают параметры, разделенные пробелами, а не запятыми.Вы можете увидеть разницу в подписи: min: 'T -> 'T -> 'T, что эквивалентно

min: int -> int -> int

Для кортежа это будет:

minT: int * int -> int

...