• # Une solution en F#

    Posté par . En réponse au message Paradigme fonctionnel : juste un habillage ?. Évalué à 3.

    Je n'ai pas de compilateur OCaml sous la main, mais voici une proposition en F#. La traduction en OCaml devrait être simple.

    open System
    let split (s : String) =
     let rec loop i j xs =
     if i = 0 then
     if j > 0 then
     s.[0 .. j - 1] :: xs
     else
     xs
     else
     if s.[i - 1] = ' ' then
     loop (i - 1) (i - 1) (s.[i .. j - 1] :: xs)
     else
     loop (i - 1) j xs
     let n = String.length s
     loop n n []
    let format width xs =
     let rec loop rs line rems =
     match rems with
     | [] -> List.rev (line :: rs)
     | hd :: tl ->
     match line with
     | "" ->
     loop rs hd tl // problème si un mot est plus long que width
     | _ ->
     let line' = line + " " + hd
     if String.length line' <= width then
     loop rs line' tl
     else
     loop (line :: rs) hd tl
     loop [] "" xs
    let s =
     [
     "Ceci"
     " est un"
     "e chaine assez "
     "longue, voir"
     "e même trop lo"
     "ngue ! Tellement longue que l'on peut se demander si elle va tenir !"
     " sur une seule ligne"
     ]
     |> String.concat ""
    Console.WriteLine("Original string: " + s)
    Console.WriteLine()
    let xs = split s
    Console.WriteLine("Split string:")
    for x in xs do
     Console.WriteLine("[" + x + "]")
    Console.WriteLine()
    let lines = format 20 xs
    Console.WriteLine("After formatting:")
    for line in lines do
     Console.WriteLine(line)
    
    

    La fonction split découpe la chaîne passée en paramètre et renvoie une liste de chaînes. La fonction format prend une liste de chaines et renvoie une liste de chaînes (une par ligne) en s'assurant qu'aucune ligne ne dépasse la largeur maxi spécifiée (sauf si un élément de la liste d'entrée est lui-même plus long que ladite largeur maxi).