0

Are there any elvis like operator in Ocaml ? Any sort of optional chaining that return the right value when the left one is empty, a default value operator, like the |> operator with opposite effect.

If not what are the good practices ?

As an example of a use case :

let get_val val_1 val_2 = 
  if (val_1) then (val_1) else (val_2);;

Are there any syntactic sugar ?

Dav
  • 17
  • 4

2 Answers2

2

First, in OCaml if ... then ... else ... is an expression and thus there is no needs to have a distinct ternary operator.

Second, OCaml has optional arguments. If I guess correctly the supposed semantics of your get_val function, it can be written:

let default = []
let get_val ?(val_1=default) () = val_1

which gives you [] as the default value when the named argument val_1 is absent

let () =
  assert ([] = get_val ())

or the val_1 argument otherwise:

let () = 
  assert ([2;3;4] = get_val ~val_1:[2;3;4] ())
octachron
  • 17,178
  • 2
  • 16
  • 23
1

Be aware that function arguments in OCaml are eagerly evaluated.

let get_val val_1 val_2 = 
  if (val_1) then (val_1) else (val_2);;

With more accurate naming:

let get_val expr1 expr2 =
  if expr1 then expr1 else expr2

In this, expr2 will always be evaluated, even if expr1 evaluates to false. If we just use the conditional expression, expr2 is only evaluated when expr1 evaluates to false.

Also keep in mind that unlike many other programming languages, the conditional expression is very strictly typed. It only works on booleans. There is no concept of arbitrary values being considered true or false. The following will result in a compile error, rather than evaluating to 27.

if 0 then 42 else 27

This means that in the code above, expr1 must have type bool and because it's a possible result of the conditional expression, the entire conditional expression must return bool, which means that expr2 has type bool. Therefore get_val as written has type bool -> bool -> bool. This is a bit restrictive and probably not as useful as you were hoping.

You could pass a predicate function to determine if expr1 is true or false to work around this.

# let get_val pred expr1 expr2 =
    if pred expr1 then expr1 else expr2;;
val get_val : ('a -> bool) -> 'a -> 'a -> 'a = <fun>
Chris
  • 26,361
  • 5
  • 21
  • 42