Apprendre + Équipe = Programmes


Découverte du langage OCaml


Cette semaine j'avais envie d'explorer un nouveau langage. Je souhaitais avoir un typage fort et des fonctions currifiées par défaut : j'ai essayé OCaml, et j'ai été agréablement surpris.

Kata Bowling en OCaml

Pour découvrir le langage, je me suis lancé sur une implémentation du kata bowling :

type roll = Roll of int

type frame = Frame of int
let next (Frame n) = Frame (n + 1)

let rec score ?(f=Frame 1) = function
  | [] -> 0
  | [Roll x; Roll y; Roll z] when is_last_frame f ->
      x + y + z
  | r1 :: (Roll y as r2) :: (Roll z as r3) :: rest when is_strike r1 ->
      10 + y + z + score ~f:(next f) (r2 :: r3 :: rest)
  | r1 :: r2 :: (Roll z as r3) :: rest when is_spare r1 r2 ->
      10 + z + score ~f:(next f) (r3 :: rest)
  | Roll x :: Roll y :: rest ->
      x + y + score ~f:(next f) rest
  | [_] -> failwith "wrong number of rolls"
and is_strike = (=) @@ Roll 10
and is_spare (Roll x) (Roll y) = 10 == x + y
and is_last_frame = (=) @@ Frame 10

Le répo github est ici, la liste des commits montre le cheminement :

Ce que j'ai apprécié

Ce que j'ai moins apprécié

Kata Bowling en Haskell

Pour explorer les ressemblances, j'ai fait le même kata en Haskell :

module Bowling (score, Roll(..)) where

data Roll = Roll Int
  deriving (Eq)

data Frame = Frame Int
  deriving (Eq)
next (Frame n) = Frame (n + 1)

score = score' $ Frame 1
score' f xs = case xs of
  [] -> 0
  r1@(Roll x):r2@(Roll y):r3@(Roll z):rest
    | isLastFrame f ->
      x + y + z
    | isStrike r1 ->
      10 + y + z + score' (next f) (r2:r3:rest)
    | isSpare r1 r2 ->
      10 + z + score' (next f) (r3:rest)
  Roll x:Roll y:rest ->
    x + y + score' (next f) rest
  [_] -> error "Wrong number of rolls"
  where
    isStrike = (==) $ Roll 10
    isSpare (Roll x) (Roll y) = 10 == x + y
    isLastFrame = (==) $ Frame 10

Sur cet exemple, les deux implémentations sont vraiment proches.

Le répo github est ici, la liste des commits montre le cheminement :

Conclusion

Je suis content d'avoir découvert OCaml, je pense en refaire plus tard, par exemple pour explorer l'orientation objet. Ou peut-être découvrir F# pour explorer encore un autre langage de ce type ?

Note : je ne suis un expert ni en OCaml, ni en Haskell. Je suis preneur d'avis pour améliorer tout ça.