OCaml, F # sequential, cascading let bindings

In OCaml or F #, it is typical to have consecutive let bindings of the form:

let a1 = ... let a2 = ... let a3 = ... let f1 = ... let f2 = ... let f3 = ... f3 a1 a2 a3 

In many cases, some of these let bindings (for example, f1 and f2 in the above example) are used only as building blocks of an expression or function immediately following them, and are not mentioned again after that. In other cases, some values ​​are actually used at the end of the chain (for example, a1 , a2, and a3 in the above example). Is there a syntactic idiom to make these differences in the field clear?

+7
source share
2 answers

On can use this to show that temp is only used in the definition of a1 :

 let a1 = let temp = 42 in temp + 2 in let a2 = ... 

The scope of temp really limited by the definition of a1 .

Another template uses the same name to hide its previous use, thus it is also clear that the previous use is temporary:

 let result = input_string inchan in let result = parse result in let result = eval result in result 

Reusing the same name is controversial.

Of course, there are always comments and blank lines:

 let a1 = ... let a2 = ... let a3 = ... (*We now define f3:*) let f1 = ... let f2 = ... let f3 = ... f3 a1 a2 a3 

Edit: as fmr pointed out, I am also fond of the pipe operator. It is not defined by default in OCaml, use

 let (|>) xf = fx;; 

Then you can write something like

 input_string inchan |> parse |> eval |> print 
+11
source

In addition to jrouquie's answer, you can avoid naming intermediate values ​​by making judicious use of composition of functions and other combinators. I especially like the following three of the Batteries :

 # let ( |> ) xf = fx;; val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun> # let ( |- ) fgx = g (fx);; val ( |- ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c = <fun> # let flip fxy = fyx;; val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c = <fun> 

A small example using |> -

 # [1;2;3] |> List.map string_of_int |> String.concat "; " |> Printf.sprintf "[%s]";; - : string = "[1; 2; 3]" 

In more realistic examples, you will need |- and flip . This is called point-free or tacit .

+7
source

All Articles