2020年10月27 平凡的变换 that makes sense ============================================ *Build FsLexYacc时不要开VSCode* idea就是编译到F# 好处: 1. 编译器能处理source location map,语法`# 17 filename.txt` 2. fsharp编译速度比较快 3. FSLexYacc 4. 平凡的AST变换,非常完备的编译器 Lambda ------------ ```fsharp fun x -> x ``` from ``` |x| x ``` Delim Cont ------------ ```fsharp let k = fun ``delim cont`` -> (x + ``delim cont``) in expr ``` from ``` reset { x + shift k expr} ``` Extensible Records(Type Definition) ---------------------------------------- ``` type Rec<'a> = { a : 'a; } ``` ```fsharp type Rec<'a> = ``Rec _`` of 'a with member this.``get a`` = let (F(a)) = this in a member this.``update a`` (f : 'a -> 'a_)= let (F(a)) = this in F(f a) interface ``Prop a``, 'a> with member this.``get a`` = this.``get a`` member this.``update a`` f = this.``update a`` f end ``` where ```fsharp type ``Prop a``<'a, 'b> = interface abstract member ``get a`` : 'b abstract member ``update a``: ('b -> 'b) -> 'a end ``` Extensible Records(Type Usage) ---------------------------------------- ``` def get_fff: forall 'a 'b when {'a.fff : 'b} . 'a -> 'b = |x| x.fff ``` to ```fsharp let get_fff<'a, 'b when 'a : ``Prop fff``<'a, 'b>> : 'a -> 'b = (fun x -> x.fff) ``` Nested Data Update ---------------------- ``` x.a.b.c by |x| x + 1 ``` to ```fsharp x.``update a`` (fun a -> a.``update b`` (fun b -> b.``update c`` (fun x -> x + 1) )) ``` ``` x.a.b.{ c by f1; d by f2; } ``` to ```fsharp x.``update a`` (fun a -> a.``update b`` (fun b -> b |> (fun b -> b.``update c`` f1) |> (fun b -> b.``update d`` f2) )) ```