Reputation: 3677
I have experience with functional programming in general, but I'm new to F#, and I can't get this code to compile no matter what I try:
let group2<'T> (sq: seq<'T>) : seq<'T * 'T> =
Seq.fold (fun (p, l) b -> match p with
| None -> (Some b, l)
| Some v -> (None, (v, b) :: l)) (None, []) sq
I don't understand what this error message is trying to tell me, and I can't for the life of me figure out why it won't compile as-is;
main.fs(2,19): error FS0001: This expression was expected to have type
'seq<'T * 'T>'
but here has type
''a * 'b'
main.fs(4,65): error FS0001: This expression was expected to have type
'seq<'T * 'T>'
but here has type
''a * 'b'
anyone with more F# experience have some advice?
Upvotes: 0
Views: 79
Reputation: 2436
So if you update your code like this
let group2<'T> (sq: seq<'T>) : seq<'T * 'T> =
Seq.fold (fun (p ,l) b -> match p with
| None -> (Some b, l)
| Some v -> (None, (v, b) :: l)) (None, []) sq
|> snd
|> List.rev
|> Seq.ofList
It can work (by removing the state, and converting back from list to sequence). For example
group2 [1;2;3;4]
yields
[(1, 2); (3, 4)]
It's not very idiomatic as it mixes sequences and lists.
A more idiomatic code only for (even) lists:
let rec group2 (xs:'T list) =
match xs with
| [] -> []
| x::y::xs -> ( x, y)::group2 xs
| _ -> failwith "not even"
Basically you deal with 3 choices,
If you want to consider odd lists, you can use option types: e.g. None/Some
let rec group2 (xs:'T list) =
match xs with
| [] -> []
| [x] -> [Some x, None]
| x::y::xs -> (Some x,Some y)::group2 xs
Finally you could use the chunkBySize library function for either (even) lists or sequences:
[1;2;3;4]
|> Seq.chunkBySize 2
|> Seq.map (fun a -> a.[0], a.[1])
or
[1;2;3;4]
|> List.chunkBySize 2
|> List.map (fun a -> a.[0], a.[1])
Upvotes: 2