Guest User

Untitled

a guest
Oct 21st, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.75 KB | None | 0 0
  1. // free monad for memory operations.
  2. // Read: int -> float
  3. // Write: int * float -> unit
  4.  
  5. (*
  6. STEP 1:
  7. Create types for input and output for each of the operations.
  8. *)
  9.  
  10. type MemReadIn = int
  11. type MemReadOut = float
  12.  
  13. type MemWriteIn = int * float
  14. type MemWriteOut = unit
  15.  
  16. (*
  17. STEP 2:
  18. Create a functor for the instructions
  19. *)
  20.  
  21. type MemInstruction<'a> =
  22. | MemRead of (MemReadIn * (MemReadOut -> 'a))
  23. | MemWrite of (MemWriteIn * (MemWriteOut -> 'a))
  24.  
  25. // (a -> b) -> Ma -> Mb
  26. let mapI f = function
  27. | MemRead (args, next) -> MemRead(args, next >> f)
  28. | MemWrite (args, next) -> MemWrite(args, next >> f)
  29.  
  30. (*
  31. STEP 3:
  32. Create a free monad for the program
  33. *)
  34.  
  35. type MemProgram<'a> =
  36. | Free of MemInstruction<MemProgram<'a>>
  37. | Pure of 'a
  38.  
  39. // (a -> Mb) -> Ma -> Mb
  40. let rec bind f = function
  41. | Free x -> x |> mapI (bind f) |> Free
  42. | Pure x -> f x
  43.  
  44. (*
  45. STEP 4:
  46. Create the computation expression builder
  47. *)
  48.  
  49. type MemBuilder () =
  50. member __.Bind (x, f) = bind f x
  51. member __.Return (x) = Pure x
  52. member __.ReturnFrom m = m
  53. member __.Zero () = Pure ()
  54.  
  55. let mem = new MemBuilder ()
  56. let memread args = Free (MemRead (args, Pure))
  57. let memwrite args = Free (MemWrite (args, Pure))
  58.  
  59. (*
  60. STEP 5:
  61. Interpreter:
  62. *)
  63. let mutable x = 0.
  64.  
  65. let read (args:MemReadIn) : MemReadOut =
  66. printfn "Read args: %O" args
  67. x
  68.  
  69. let write (args:MemWriteIn) : MemWriteOut =
  70. printfn "Write args: %O" args
  71. let (i, v) = args
  72. x <- v
  73. ()
  74.  
  75. let rec interpret = function
  76. | Pure x -> x
  77. | Free (MemRead (x, next)) -> x |> read |> next |> interpret
  78. | Free (MemWrite (x, next)) -> x |> write |> next |> interpret
  79.  
  80. (*
  81. TESTS
  82. *)
  83.  
  84. let workflow = mem {
  85. do! memwrite (1, 10.)
  86. let! x = memread (1)
  87. return x
  88. }
  89.  
  90. workflow |> interpret |> printfn "Res: %O"
Add Comment
Please, Sign In to add comment