RosettaCodeData/Task/Amb/F-Sharp/amb.fs

29 lines
928 B
Forth

// define the List "workflow" (monad)
type ListBuilder() =
member o.Bind( lst, f ) = List.concat( List.map (fun x -> f x) lst )
member o.Return( x ) = [x]
member o.Zero() = []
let list = ListBuilder()
let amb = id
// last element of a sequence
let last s = Seq.nth ((Seq.length s) - 1) s
// is the last element of left the same as the first element of right?
let joins left right = last left = Seq.head right
let example = list { let! w1 = amb ["the"; "that"; "a"]
let! w2 = amb ["frog"; "elephant"; "thing"]
let! w3 = amb ["walked"; "treaded"; "grows"]
let! w4 = amb ["slowly"; "quickly"]
if joins w1 w2 &&
joins w2 w3 &&
joins w3 w4
then
return String.concat " " [w1; w2; w3; w4]
}
printfn "%s" (List.head example)