1. 7
  1. 5

    Other types of non-OO encapsulation:

    Hiding the existence of a value inside a closure:

    utop#
    let make_counter () =
      let counter = ref 0 in
      (fun () -> !counter), (fun () -> counter := !counter + 1)
    ;;
    utop# let (read, increment) = make_counter () ;;
    
    utop # increment () ;;
    - : unit = ()
    
    utop # read () ;;
    - : int = 1
    

    Hiding the nature of a value with an abstract type:

    utop # module type TotallyNotString = sig
      type t
      val from_string : string -> t
      val print_endline : t -> unit
    end
    ;;
    
    utop # module NotString : TotallyNotString = struct
      type t = string
      let print_endline s = Stdlib.print_endline s
      let from_string s = s
    end ;;
    
    utop # NotString.print_endline "hello world" ;;
    Error: This expression has type string but an expression was expected of type
             NotString.t
    
    utop # NotString.print_endline @@ NotString.from_string "hello world" ;;
    hello world
    - : unit = ()
    
    
    
    1. 2

      Isnt encapsulation a feature of … any “function”? It isn’t typically a language feature of “data” in FP that a function might transform. The article seems to be scratching one’s left ear with one’s right hand to address this conundrum?