We are implementing this algorithm in F#.
Here is a little bit more information from Topor (1982) about the notation that the algorithm uses:
Formally, a
't list
is eithernull
(denotednil
) or has ahd
(which is a't
) and atl
(which is a't list
)... Ifx
is a list, we test whether it isnull
by writingnull x
... We create a new list, adding the elementa
at the front of an existing listx
, by writinga:x
... We denote the unit list containing the elementa
bylist(a)
...list(x) = x:nil
.
What we're wondering is how in F# to express those nil
, null
, and list(nil)
values. For instance, should we be using the Option type, an empty list, or something else?
let rec kpermute k (xs: 't list) =
let rec mapPerm k xs ys =
match ys with
| [] -> []
| head::tail ->
let kpermuteNext = kpermute (k-1) (removeFirst head xs)
let mapPermNext = mapPerm k xs tail
mapcons head kpermuteNext mapPermNext
match k with
| 0 -> [[]]
| _ when xs.Length < k -> []
| _ -> mapPerm k xs xs
When working with lists, for list(nil)
we use [[]]
and for nil
we use []
. While that's fine, there might be a more expressive way to do it. There are also times when we use List.empty<'t list>
and List.empty<'t>
when the type inference needs more information.
The paper gives you all the answers: nil
is []
; null x
is a test for whether x
is the empty list; list(nil)
is [[]]
.
The naïve translation of algorithm B to F# is as follows:
let rec minus a = function
| [] -> failwith "empty list"
| xh :: xt -> if xh = a then xt else xh :: minus a xt
let rec permute2 k x =
if k = 0 then [[]]
elif List.length x < k then []
else mapperm k x x
and mapperm k x = function
| [] -> []
| yh :: yt -> mapcons yh (permute2 (minus yh x)) (mapperm x yt)
and mapcons a ps qs =
match ps with
| [] -> qs
| ph :: pt -> a :: ph :: mapcons a pt qs
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.