我通过做一些简单的矩阵数学来教自己一些F#。我决定编写一组简单的函数来合并两个矩阵,因为我认为这将是学习列表理解的一种好方法。但是,当我编译它时,我的单元测试会产生类型不匹配异常。
//return a column from the matrix as a list
let getColumn(matrix: list<list<double>>, column:int) =
[for row in matrix do yield row.Item(column)]
//return a row from the matrix as a list
let getRow(matrix: list<list<double>>, column:int) =
matrix.Item(column)
//find the minimum width of the matrices in order to avoid index out of range exceptions
let minWidth(matrix1: list<list<double>>,matrix2: list<list<double>>) =
let width1 = [for row in matrix1 do yield row.Length] |> List.min
let width2 = [for row in matrix2 do yield row.Length] |> List.min
if width1 > width2 then width2 else width1
//find the minimum height of the matrices in order to avoid index out of range exceptions
let minHeight(matrix1: list<list<double>>,matrix2: list<list<double>>) =
let height1 = matrix1.Length
let height2 = matrix2.Length
if height1 > height2 then height2 else height1
//combine the two matrices
let concat(matrix1: list<list<double>>,matrix2: list<list<double>>) =
let width = minWidth(matrix1, matrix2)
let height = minHeight(matrix1, matrix2)
[for y in 0 .. height do yield [for x in 0 .. width do yield (List.fold2 (fun acc a b -> acc + (a*b)), getRow(matrix1, y), getColumn(matrix2, x))]]
我期望函数返回类型为
的列表double list list
实际上返回的内容更像是某种lambda表达式
((int -> int list -> int list -> int) * double list * double list) list list
有人可以告诉我返回什么,以及如何将其评估为我最初期望的列表列表吗?
答案 0 :(得分:2)
对于您的问题,答案很简短。
简短的说法是F#函数(例如List.fold2
)采用多个参数,而不是您认为的逗号,而是在两者之间留有空格。也就是说,您不应像这样呼叫List.fold2
:
List.fold2 (function, list1, list2)
但是像这样:
List.fold2 function list1 list2
现在,如果仅删除List.fold2
调用中的逗号,则会看到编译器抱怨getRow(matrix1, y)
调用,并告诉您在括号中加上括号。 (并且实际上不需要List.fold2
周围的一对括号)。所以这个:
(List.fold2 (fun acc a b -> acc + (a*b)), getRow(matrix1, y), getColumn(matrix2, x))
需要变成这样:
List.fold2 (fun acc a b -> acc + (a*b)) (getRow(matrix1, y)) (getColumn(matrix2, x))
F#函数采用多个参数的方式实际上与大多数其他语言(例如C#)非常不同。实际上,所有F#函数都只使用一个参数! “但是等等,”您可能现在正在想,“您现在向我展示了带有多个参数的F#函数的语法!”是的,我做到了。实际情况是 currying 和部分应用的组合。我会写一个很长的解释,但是Scott Wlaschin已经写了一个解释,这比我可以写的要好得多,因此,我仅向您指出https://fsharpforfunandprofit.com/series/thinking-functionally.html系列,以帮助您了解这里的情况。 (有关currying和部分应用程序的部分是您想要的,但是我建议按顺序阅读该系列文章,因为后面的部分建立在前面的部分中介绍的概念上。)
是的,这个“长”答案似乎比“短”答案要短,但是如果您阅读该系列文章(然后阅读Scott Wlaschin优秀网站的其余部分),则会发现它比简短的答案要长得多。回答。 :-)
如果您还有其他问题,我们将很乐意为您解释。