How to specify list type in function parameter?

I have a function that takes two lists and generates a Cartesian product.

let cartesian xs ys = xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))

My problem is that I pass two lists of type Int64, and I get errors because the function expects two lists of type Int32.

How do I explicitly set the list type?

+4
source share
2 answers

Adding type annotation to one of the arguments should work:

let cartesian (xs: int64 list) ys =
  xs |> List.collect (fun x -> ys |> List.map (fun y -> x * y))

Alternatively, use the following inlineto output types to the call site:

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]
+5
source

Extended comment: there is a third alternative that decomposes a piece of code that introduces a restriction. Since the multiplication operator F # has a signature

val inline ( * ) : ^T1 -> ^T2 -> ^T3
    when (^T1 or ^T2) : (static member (*) : ^T1 * ^T2 -> ^T3)

, , , . :

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]
+4

Source: https://habr.com/ru/post/1695290/


All Articles