在F#上的函数签名中定义元组数据类型



我想定义元组元素的预期数据类型,这些元素将被传递给调用函数。当我不定义它并让类型推理工作时,这是可以的,但现在我想写一些小函数,这些函数仍然没有在任何地方被调用,我不知道如何定义参数。

这个例子。我希望description是一个元组,其中五个元素中的每一个都是int,然后提取要处理的每个部分。

let setArray (description: int * int * int * int * int)  =
let id = fun (i, _, _, _, _) -> i
let startX = fun (_, x, _, _, _) -> x
let startY = fun (_, _, y, _, _) -> y
let width = fun (_, _, _, w, _) -> w
let height = fun (_, _, _, _, h) -> h
let arrayResult = Array2D.init (width + 1) (height + 1) (fun i j -> if i < width &&  j < height then id)
arrayResult

.fsx(29,45(:错误FS0001:类型"int"与类型"'a*'b*'c*'d*'e->'d'不匹配

对于其他函数,如我所说,类型推理有效,我可以使用模式匹配而不会出现问题

let getMaxCoords =
let x = elements |> Seq.map (fun (_, x, _, _, _) -> x) |> Seq.max
let y = elements |> Seq.map (fun (_, _, y, _, _) -> x) |> Seq.max
x, y

我做错了什么?

首先,下面的代码块定义了五个函数,而不是五个整数值:

let setArray (description: int * int * int * int * int)  =
let id = fun (i, _, _, _, _) -> i
let startX = fun (_, x, _, _, _) -> x
let startY = fun (_, _, y, _, _) -> y
let width = fun (_, _, _, w, _) -> w
let height = fun (_, _, _, _, h) -> h

您可能想做的是将description元组传递到这些析构函数中的每一个,如下所示:

let setArray (description: int * int * int * int * int)  =
let id = description |> (fun (i, _, _, _, _) -> i)
let startX = description |> (fun (_, x, _, _, _) -> x)
let startY = description |> (fun (_, _, y, _, _) -> y)
let width = description |> (fun (_, _, _, w, _) -> w)
let height = description |> (fun (_, _, _, _, h) -> h)

但有一种更简单的方法可以做到这一点。F#允许您对函数签名中的元组进行解构。因此,您可以用以下内容替换整个代码块:

let setArray (id, startX, startY, width, height) =

就是这样!所以现在你的整个功能看起来像:

let setArray (id, startX, startY, width, height) =
let arrayResult = Array2D.init (width + 1) (height + 1) (fun i j -> if i < width && j < height then id)
arrayresult

还有一个你可以做的简化。任何时候,只要let x = (some calculation)后面紧跟着x作为函数的返回值,就可以去掉let,让函数返回(some calculation)。应用这种简化,你的功能就变成了:

let setArray (id, startX, startY, width, height) =
Array2D.init (width + 1) (height + 1) (fun i j -> if i < width && j < height then id)

你完了!如果你真的想指定idstartX等都是整数,你可以这样做:

let setArray (id : int, startX : int, startY : int, width : int, height : int) =
Array2D.init (width + 1) (height + 1) (fun i j -> if i < width && j < height then id)

最新更新