Sal-laS
Sal-laS

Reputation: 11649

The type int is not compatible with type seq<'a>

consider i have the following code,

let sqx= seq [1; 2; 3; 4;]
let sqy= seq [1; 2; 3; 4;]

let func sqx sqy = seq{ 
         for x in sqx do
            for y in sqy do yield x,y    } 

let cartesian sqx sqy= Seq.map (func sqx) sqy 

cartesian sqx sqy

at the last line i am facing with the erorr:

The type int is not compatible with type seq<'a>

I have also tried to work with Seq.map2, but still the same problem.

Upvotes: 0

Views: 1419

Answers (2)

Random Dev
Random Dev

Reputation: 52280

My first guess is that you want something like seq [(1, 1); (1, 2); (1, 3); (1, 4); ...] (which would be the cartesian product of your sqx and sqy) and indeed you have this already implemented:

> func sqx sqy;;
val it : seq<int * int> = seq [(1, 1); (1, 2); (1, 3); (1, 4); ...]

but maybe you want to apply some function to all combinations of x in sqx and y in sqy? Then can modify your code a bit:

let allWith f sqx sqy = 
    seq{ for x in sqx do
         for y in sqy do 
         yield f x y } 

and have some fun:

> allWith (fun x y -> (x,y)) sqx sqy;;
val it : seq<int * int> = seq [(1, 1); (1, 2); (1, 3); (1, 4); ...]
> allWith (+) sqx sqy;;
val it : seq<int> = seq [2; 3; 4; 5; ...]

or maybe you want to write a function that takes the cartesian product of a sequence of sequences? This is more fun:

let rec cartesian (xss : 'a seq seq) =
    if Seq.isEmpty xss then Seq.singleton Seq.empty else
    let first = Seq.head xss
    let rests = cartesian (Seq.tail xss)
    seq { for x in first do
          for xs in rests do
          yield seq { yield x; yield! xs }
    }

here is a simple example:

> cartesian [[1;2;3];[4];[5;6]] |> Seq.toArray;;
val it : seq<int> [] =
  [|seq [1; 4; 5]; seq [1; 4; 6]; seq [2; 4; 5]; seq [2; 4; 6]; seq [3; 4; 5];
    seq [3; 4; 6]|]

Upvotes: 0

Mark Seemann
Mark Seemann

Reputation: 233150

If you look at the types involved, it may help you understand why the compiler complains.

The type of func is seq<'a> -> seq<'b> -> seq<'a * 'b>. That is, incidentally, also the type of Seq.zip; consider replacing func with Seq.zip.

The type of Seq.map is ('a -> 'b) -> seq<'a> -> seq<'b>.

If you look at cartesian, it simply it calls Seq.map with two arguments. The second argument is easiest to think about. From the type of Seq.map, we know that it must be seq<'something>.

That also means that func sqx must fit into the type 'a -> 'b, or, more specifically 'something -> 'b.

The type of func sqx, on the other hand, is seq<'b> -> seq<'a * 'b>, because it's partially applied. In other words, the input is seq<'b>.

This must fit into the 'something -> 'b argument passed to Seq.map, so 'something must be seq<'b>, and the return type is inferred to be seq<'a * 'b>. Thus, the overall type of cartesian is seq<'a> -> seq<#seq<'c>> -> seq<seq<'a * 'c>>.

The first argument to cartesian must be seq<'a>. That's OK, because sqx has the type seq<int>.

The next argument to cartesian must be seq<#seq<'c>>, but sqy has the type seq<int>. That's not the same type, and that's the reason cartesian sqx sqy doesn't compile.

Upvotes: 1

Related Questions