I have code which boils down to the following (at a basic level):
#r @"nuget: FSharpPlus"
open FSharpPlus
type Position = Position of int
type Thing =
| Doodah
| Widget
| Gizmo
type Whatsit =
| Doodah of Position
| Widget of Position
| Gizmo of Position
let describe whatsit =
match whatsit with
| Doodah (Position position) -> "Doodah " + position.ToString()
| Widget (Position position) -> "Widget " + position.ToString()
| Gizmo (Position position) -> "Gizmo " + position.ToString()
let things = [Doodah; Widget; Doodah; Widget; Gizmo]
let whatsits = things |> List.rev |> List.mapi (fun i thing -> thing (Position i)) |> List.rev
whatsits |> List.map describe |> List.intersperse ", " |> List.reduce (+)
// val whatsits: Whatsit list =
// [Doodah (Position 4); Widget (Position 3); Doodah (Position 2);
// Widget (Position 1); Gizmo (Position 0)]
// val it: string = "Doodah 4, Widget 3, Doodah 2, Widget 1, Gizmo 0"
However, I would like the last separator to be sometimes different, dependant upon specific rules which are:
(1) If there is zero or one Whatsit then there is no separator.
(2) If there is more than one Whatsit then the separator between the Whatsit with Position 0 (if there is one) and the next Whatsit (to its left in the list above) should be:
(a) “, “ if the Whatsit with Position 0 is a Gizmo, or;
(b) “and “ if the Whatsit with Position 0 is a Widget or a Doodah.
(3) Separators between all other Whatsits should be “, “.
Some expected example outputs are:
“Gizmo 0”
“Widget 0”
“Doodah 0”
“Gizmo 1, Gizmo 0”
“Gizmo 1 and Widget 0”
“Gizmo 1 and Doodah 0”
“Gizmo 2, Doodah 1” (There may not be anything at Position 0)
“Gizmo 2, Widget 1, Gizmo 0”
“Gizmo 2, Widget 1 and Widget 0”
“Doodah 3, Widget 2, Gizmo 1 and Doodah 0”
“Doodah 4, Gizmo 2 and Doodah 0” (some Whatsits may be removed from the list before adding the separators)
Is there a way to do this?
I’ve looked at List.fold and List.mapFold but I don’t think I can quite get my head around how to use these for this sort of thing where the number of elements is different to the number of separators.