1
votes

I would like to generate a sequence of sequences of sets of tuple

It's for generating coordinates of lines in board game (squares);horizontal lines,vertical lines, and the main 2 diagonal lines

The one I created using list (using the generateLines function) works well. It generates the coordinates of lines in a list of lists of tuples. However, after I convert it into sequence of sequences, I don't have any idea how to check whether it's correct

I've tried this : CoordinateLines 3 |> Seq.map (fun x ->Seq.toList) |> Seq.toList

But it doesn't work, with error : error FS0030: Value restriction. The value 'it' has been inferred to have generic type val it : ('_a -> '_b list) list when '_a :> seq<'_b>
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

let CoordinateLines size : seq<seq<int*int>> =  
    let generateLines size = 
        [for a in 0..(size-1) do

        yield [for b in 0..(size-1) do
        yield(a,b)
        ]
        ]
        @
        [for a in 0..(size-1) do

        yield [for b in 0..(size-1) do
        yield(b,a)
        ]
        ] 
        @
        [[for a = 0 to (size-1) do
        yield (a,(size-1)-a)

        ]]
        @
        [[for a = 0 to (size-1) do
        yield (a,a)
        ]]
    generateLines size 
    |> List.toSeq 
    |> Seq.map (fun x -> List.toSeq x)
1

1 Answers

3
votes

You are getting this error, because you forgot to pass x as the argument to Seq.toList in the lambda function passed to Seq.map. The following works fine:

CoordinateLines 3 |> Seq.map (fun x ->Seq.toList x) |> Seq.toList

Alternatively, you can also use Seq.toList directly as the argument to Seq.map:

CoordinateLines 3 |> Seq.map Seq.toList |> Seq.toList

That said, I don't see any reason for converting the lists to seq<'a> - the list type implements the seq<'a> interface already, so anything that you want to do with sequences will also work with lists. And since you are generating fully evaluated lists already, it might actually turn out that you can write some subsequent logic more nicely using lists.

If I was doing this, I'd just write a function that returns list of lists. You can also use the
[ for <var> in <range> -> <expr> ] notation (which lets you omit some yield keywords), and you can avoid using @ by putting all the code that generates nested list in one big [ .. ] block with multiple nested fors and yields. This makes your code a bit shorter:

let CoordinateLines size =  
    [ for a in 0..(size-1) ->
        [ for b in 0..(size-1) -> (a,b) ] 
      for a in 0..(size-1) ->
        [ for b in 0..(size-1) -> (b,a) ] 
      yield [ for a in 0..(size-1) -> (a,(size-1)-a) ] 
      yield [ for a in 0..(size-1) -> (a,a) ] ]