F# FS0001:此表达式应具有 figure 类型,但她具有 int*int 类型

F# FS0001: This Expression was expected to have type figure, but her has type int*int

我目前正在开发一个程序,该程序应该采用 'figure' 并沿矢量移动它。为此,我创建了函数 'move',它接受一个 'figure' 和一个向量。 然后我尝试使用模式匹配来更新图形的值。

type point = (int*int)
type figure =
 |Circle of point * int * string
 |Rectangle of point * point * string
 |Mix of figure * figure 

let circ = Circle((50,50),45,"Red")
let rect = Rectangle((40,40),(90,110),"Blue")
let figTest : figure = Mix(circ,rect)

我有以上类型和起始数字,'figTest'。 然后我调用 'move figTest',但它给出错误 FS0001:此表达式应具有类型 'figure' 但此处具有类型 'int * int -> figure'.

let rec move figure (v:int*int) : figure= 
 let vx = fst v
 let vy = snd v
 
 match figure with
 | Circle ((cx,cy) , radius, colour) -> Circle(point(cx + vx, cy-vy), radius, colour)
 | Rectangle((x0,y0), (x1,y1), colour) -> Rectangle(point(x0 + vx, y0 + vy),point(x1 + vx, y1 + vy), colour)
 | Mix(f1,f2) ->
     let newCirc = move(f1)
     let newRect = move(f2)
     let newFig = Mix(newCirc, newRect)
     newFig

当我给 'newFig' 新的圆形和矩形时似乎出现了错误,但我不太明白哪里出了问题。我经常在 f# 中遇到这些类型错误,所以我以为我已经掌握了窍门,但我就是找不到原因...

这离工作很近了,所以不要气馁。有两个小问题:

  1. 当你递归调用move时,你必须再次传递v。所以 let newCirc = move f1 v 是正确的而不是 let newCirc = move(f1)。 (请注意,newCirc 实际上可能不是一个圆,因此您可能希望使用不同的变量名称。)

  2. 由于point只是int * int的同义词,它没有自己的构造函数。所以 (cx + vx, cy-vy) 是正确的而不是 point(cx + vx, cy-vy).

当我进行这两项更改时,您的代码对我来说工作正常。您的代码还有许多其他问题需要解决,但目前只有这两个问题是阻碍因素。