You're trying to yield
an 'a seq
as a single element of a sequence which has type 'a seq
. For that to work, then 'a
must be the same type as 'a seq
, and so on, so the type is "infinite" - you'd have to have nested them infinitely for it to "work".
I see in your answer that you recognised you have to loop through the sequence elements somehow. You can, as you have, use the for .. in
syntax to iterate through, or F# gives you the yield!
operator which actually does this for you. In this spirit, your answer could be written as
let rec permute (choices : 'a seq) (permBuilder: 'a seq) : seq<seq<'a>>= seq {
if Seq.isEmpty choices then
yield permBuilder
else
for choice in choices do
let remaining = choices |> Seq.where (fun el -> el <> choice)
let newBuilder = concatElement choice permBuilder
yield! permute remaining newBuilder }
Or, alternatively, we can use the Seq.collect
function to automatically gather a sequence of sequences (of sequences!) for us, and we're left with nice functional-style code with no explicit iterators:
let prepend element sequence = seq { yield element; yield! sequence }
let rec permute input =
if Seq.length input <= 1 then Seq.singleton input
else
let without element = Seq.where ((<>) element) input
let permutations element = permute (without element) |> Seq.map (prepend element)
Seq.collect permutations input
Something to consider, though: what happens if you have two elements which aren't distinct? For example, what happens if you try to get the permutations of [1; 1; 2]
? Your current method can't handle this neatly - even if you improved the without
closure, you'd get duplicate answers.