F# 如何在函数参数中指定列表类型?

F# 如何在函数参数中指定列表类型?,f#,F#,我有一个函数,它接受两个列表并生成笛卡尔积 let cartesian xs ys = xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y)) 我的问题是我正在传递两个类型为Int64的列表,并且由于函数需要两个类型为Int32的列表,所以出现了错误 如何显式设置列表类型 向其中一个参数添加类型注释应该可以: let cartesian (xs: int64 list) ys = xs |>

我有一个函数,它接受两个列表并生成笛卡尔积

let cartesian xs ys = xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))
我的问题是我正在传递两个类型为Int64的列表,并且由于函数需要两个类型为Int32的列表,所以出现了错误


如何显式设置列表类型

向其中一个参数添加类型注释应该可以:

let cartesian (xs: int64 list) ys =
  xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))
或者,使用
inline
推断呼叫站点的类型:

let inline cartesian xs ys =
  xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))
> cartesian [1;2;3] [1;2;3];;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]
> cartesian [1L;2L;3L] [1L;2L;3L];;
val it : int64 list = [1L; 2L; 3L; 2L; 4L; 6L; 3L; 6L; 9L]
let cartesian f xs ys =
    List.collect (fun x -> List.map (f x) ys) xs
// val cartesian : f:('a -> 'b -> 'c) -> xs:'a list -> ys:'b list -> 'c list

cartesian (*) [1L..3L] [1L..3L]
// val it : int64 list = [1L; 2L; 3L; 2L; 4L; 6L; 3L; 6L; 9L]

扩展注释:存在第三种选择,将引入约束的代码部分分解出来。因为F#乘法运算符有签名

它的静态成员约束不能被泛化,除非它出现的代码被标记为内联。将接线员移动到呼叫站点:

let inline cartesian xs ys =
  xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))
> cartesian [1;2;3] [1;2;3];;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]
> cartesian [1L;2L;3L] [1L;2L;3L];;
val it : int64 list = [1L; 2L; 3L; 2L; 4L; 6L; 3L; 6L; 9L]
let cartesian f xs ys =
    List.collect (fun x -> List.map (f x) ys) xs
// val cartesian : f:('a -> 'b -> 'c) -> xs:'a list -> ys:'b list -> 'c list

cartesian (*) [1L..3L] [1L..3L]
// val it : int64 list = [1L; 2L; 3L; 2L; 4L; 6L; 3L; 6L; 9L]

这似乎有效。看来我没有正确地解释这个论点。