News for hackers. Stuff that matters.
Re:From dependency injection to dependency rejection by yawaramin on Sunday February 05, 2017 @02:17PM (#13573996)
It's not any lack on your part. F# doesn't really support the really helpful abstraction techniques like parameterised modules or typeclasses. You can roll your own typeclasses using just simple records containing functions. It's easy, idiomatic, and it works statically. E.g., imagine you have a users 'service', with operations 'get by ID', 'add', and 'rename':

    (** Type-safe IDs using a phantom type. *)
    module Id =
      type 'a t = private T of uint64

      let of_uint64 u = T u
      let to_uint64 (T u) = u

    (** A domain type. *)
    module User =
      type t = private { id : t Id.t; name : string; age : int }

      let make uid name age : t = ...
      ...

    (** Users service typeclass. *)
    module User_service =
      type t =
        { get_by_id : User.t Id.t -> User.t Async
          add : User.t -> unit Async
          rename : string -> User.t Id.t -> unit Async }

      let db : t =
        { get_by_id = fun uid -> ...
          add = fun u -> ...
          rename = fun name uid -> ... }

      let test : t =
Now, injecting a user service dependency into any function is equivalent to passing in a parameter of type `User_service.t`.

As for free monads, I don't think F# will make them easy. If you notice, one commenter in that GitHub discussion mentioned they were doing a lot of copy-pasting to implement FMs. Imho that's a bad sign.

There are no comments on this comment yet.