the code implements this code kata: https://codingdojo.org/kata/Diamond/ This is my very first ocaml program, looking for any kind of feedback, as I'm a total ocaml noob.
It uses JaneStreet's Base and Stdio as well as cmdliner.
open Base
open Printf
open Stdio
open Cmdliner
exception DiamondError of string
let ascii_a = Char.to_int 'A'
let const_init_list n elem =
List.init n ~f: (fun _ -> elem)
let make_line depth i = if depth = 1 then
['A']
else
let line_width = 2 * depth - 1 in
if i = 0 then
let dots = const_init_list ((line_width - 1) / 2) ' ' in
dots @ ['A'] @ dots
else
let n_inner_dots = (i - 1) * 2 + 1 in
let n_outer_dots = (line_width - n_inner_dots - 2) / 2 in
let outer_dots = const_init_list n_outer_dots ' ' in
let inner_dots = const_init_list n_inner_dots ' ' in
let char_list = [Char.of_int_exn (ascii_a + i)] in
outer_dots @ char_list @ inner_dots @ char_list @ outer_dots
let get_upper_triangle d =
List.init d ~f: (fun i -> make_line d i |> String.of_char_list)
let render_diamond letter =
let triangle_depth = Char.to_int letter - ascii_a + 1 in
if triangle_depth < 0 || triangle_depth > 26 then
raise @@ DiamondError (sprintf "%c is invalid" letter)
else
let upper_triangle = get_upper_triangle triangle_depth in
if triangle_depth > 1 then
upper_triangle @ (List.tl_exn @@ List.rev upper_triangle)
else
upper_triangle
let main letter =
let diamond = try render_diamond letter with
DiamondError s -> print_endline(s); Stdlib.exit 1
in
List.iter ~f: print_endline diamond
let letter =
let doc = "The letter that determines which diamond is printed" in
Arg.(required & pos 0 (some char) None & info [] ~doc ~docv:"LETTER")
let render_diamond_t = Term.(const main $ letter)
let cmd = Cmd.v (Cmd.info "diamond") render_diamond_t
let () = Stdlib.exit @@ Cmd.eval cmd
const_init_list
you can replace(fun _ -> elem)
with(Fn.const elem)
from Base or(Fun.const elem)
from Stdlib. \$\endgroup\$