Generic type persistence without η extension

What I do: I write a small interpreter system that can parse a file, turn it into a sequence of operations, and then load thousands of data sets into this sequence to extract some final values ​​from each. A compiled interpreter consists of a list of pure functions that take two arguments: a data set and an execution context. Each function returns a modified execution context:

type ('data, 'context) interpreter = ('data -> 'context -> 'context) list

A compiler is, in essence, a tokenizer with the final step of converting a marker into a command that uses a map description defined as follows:

type ('data, 'context) map = (string * ('data -> 'context -> 'context)) list

A typical use of the interpreter is as follows:

let pocket_calc = 
  let map = [ "add", (fun d c -> c # add d) ;
              "sub", (fun d c -> c # sub d) ;
              "mul", (fun d c -> c # mul d) ]
  in 
  Interpreter.parse map "path/to/file.txt"

let new_context = Interpreter.run pocket_calc data old_context

: , pocket_calc , add, sub mul, data ).

pocket_calc , , : 'data 'context , , .

eta-expand , :

let pocket_calc data context = 
  let map = [ "add", (fun d c -> c # add d) ;
              "sub", (fun d c -> c # sub d) ;
              "mul", (fun d c -> c # mul d) ]
  in 
  let interpreter = Interpreter.parse map "path/to/file.txt" in
  Interpreter.run interpreter data context

:

  • , , . ( ) .

  • , , , , , ( ).

  • , (, "div").

: , eta-? , - ? , , , eta- ? !

+3
2

eta-expand :

 let pocket_calc data context = 
   let map = [ "add", (fun d c -> c # add d) ;
               "sub", (fun d c -> c # sub d) ;
               "mul", (fun d c -> c # mul d) ]
   in 
   let interpreter = Interpreter.parse map "path/to/file.txt" in
   Interpreter.run interpreter data context

:

  • , , . ( , ) .

, . - ( , Interpreter.run to interpreter , fun).

 let pocket_calc = 
   let map = [ "add", (fun d c -> c # add d) ;
               "sub", (fun d c -> c # sub d) ;
               "mul", (fun d c -> c # mul d) ]
   in 
   let interpreter = Interpreter.parse map "path/to/file.txt" in
   fun data context -> Interpreter.run interpreter data context
+4

, , ( , ) , , . , , , .

:

type 'a primitives = <
  add : 'a -> 'a;
  mul : 'a -> 'a; 
  sub : 'a -> 'a;
>

, :

type op = { op : 'a . 'a -> 'a primitives -> 'a }

let map = [ "add", { op = fun d c -> c # add d } ;
            "sub", { op = fun d c -> c # sub d } ;
            "mul", { op = fun d c -> c # mul d } ];;

: :

 val map : (string * op) list

: , , . , - : " add/sub/mul" " add/sub/mul/div" ( ), , , .

, , "" . , .

, . , , , Caml. ( , a :> b, a -> b), , , , , .

, . 3.12 , , , , .

, , . , " " ( ), , .

, , . , , : .., "" . , . , , , , : , , ..

, "reified" , : , . " " , , , , . , / , , " " "n-ary operations", .

+3

Source: https://habr.com/ru/post/1771273/


All Articles