FSharp · Script
module Holditch =
let allIndexOf (str: string) (c: string) =
let rec inner (s: string) acc =
match s.IndexOf c, s.IndexOf c + 1 = s.Length with
-1, _ -> acc
| x, true -> x :: acc
| x, false -> inner <| s.Substring (x + 1) <| x :: acc
inner str []
(*-------------------------------------------------------------------*)
(*-------------------------------------------------------------------*)
module Sehnsucht =
module Comprehension =
let allIndexOf str1 str2 = [
let lgt2 = String.length str2
for i in 0 .. String.length str1 - lgt2 do
if str1.[i .. i + lgt2 - 1] = str2
then yield i
]
(*-----------------------------------------------------------------*)
module RecursionWithAccumulator =
let allIndexOf str1 str2 =
let lgt1, lgt2 = String.length str1, String.length str2
let rec inner idx acc =
if idx > lgt1 - lgt2
then acc
else inner (idx + 1) <| if str1.[idx .. idx + lgt2 - 1] = str2
then idx :: acc
else acc
inner 0 []
|> List.rev // needed to reorder correctly results
(*-----------------------------------------------------------------*)
module RecursionWithContinuation =
let allIndexOf str1 str2 =
let lgt1, lgt2 = String.length str1, String.length str2
let rec inner idx cont =
if idx > lgt1 - lgt2
then cont
else inner (idx + 1) <| if str1.[idx .. idx + lgt2 - 1] = str2
then (fun acc -> cont (idx :: acc))
else cont
inner 0 id []
(*-------------------------------------------------------------------*)
(*-------------------------------------------------------------------*)
module Program =
[<EntryPoint>]
let main _ =
// type annotation needed for printf to know it's not really a string
[
("Using Holditch : %A": Printf.TextWriterFormat<_>), Holditch.allIndexOf
"Using Sehnsucht.Comprehension : %A", Sehnsucht.Comprehension.allIndexOf
"Using Sehnsucht.RecursionWithAccumulator : %A", Sehnsucht.RecursionWithAccumulator.allIndexOf
"Using Sehnsucht.RecursionWithContinuation : %A", Sehnsucht.RecursionWithContinuation.allIndexOf
]
|> List.iter (fun (msg, fct) ->
printfn msg <| fct "foobar" "o"
printfn msg <| fct "foobarmanhelloman" "man"
printfn "")
0 // exit code