nicolas
nicolas

Reputation: 9815

deriving implementation in OCaml

The best code is code that does not exist, and in that regard, Haskell has great support for deriving implementation (that became even better with deriving via).

{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE KindSignatures, PolyKinds#-}

import Data.Kind (Type)

data NTree (a :: Type) =
    NLeaf a
  | NNode (NTree (a,a))
      deriving (Eq, Ord, Read, Show, Functor, Foldable, Traversable)

As far as I can tell, the same in OCaml requires a bit of manual plumbing


type 'a n_tree = NLeaf of 'a | NNode of ('a * 'a) n_tree (* [@@deriving map] fails *)


let rec map_ntree : 'a 'b. 'a n_tree -> ('a -> 'b) -> 'b n_tree =
 fun t f ->
  match t with
  | NLeaf x -> NLeaf (f x)
  | NNode p -> NNode (map_ntree p (fun (l, r) -> (f l, f r)))

What's the status of these derivations in OCaml?

Is there a better way to supply automatically the corresponding proof trees as of now?

Would it be hard to make some similar more powerful deriving extension?

Upvotes: 2

Views: 390

Answers (1)

ivg
ivg

Reputation: 35250

There are a few ppx derivers available in opam, try opam search ppx. As an example, you can use ppx_deriving, e.g., in the OCaml top-level,

# #use "topfind";;
# #require "ppx_deriving.std";;
# type 'a n_tree = NLeaf of 'a | NNode of 'a * 'a n_tree 
  [@@deriving show, eq, ord, iter, fold, map];;
type 'a n_tree = NLeaf of 'a | NNode of 'a * 'a n_tree
val pp_n_tree :
  (Ppx_deriving_runtime.Format.formatter -> 'a -> Ppx_deriving_runtime.unit) ->
  Ppx_deriving_runtime.Format.formatter ->
  'a n_tree -> Ppx_deriving_runtime.unit = <fun>
val show_n_tree :
  (Ppx_deriving_runtime.Format.formatter -> 'a -> Ppx_deriving_runtime.unit) ->
  'a n_tree -> Ppx_deriving_runtime.string = <fun>
val equal_n_tree :
  ('a -> 'a -> Ppx_deriving_runtime.bool) ->
  'a n_tree -> 'a n_tree -> Ppx_deriving_runtime.bool = <fun>
val compare_n_tree :
  ('a -> 'a -> Ppx_deriving_runtime.int) ->
  'a n_tree -> 'a n_tree -> Ppx_deriving_runtime.int = <fun>
val iter_n_tree : ('a -> unit) -> 'a n_tree -> unit = <fun>
val fold_n_tree : ('a -> 'b -> 'a) -> 'a -> 'b n_tree -> 'a = <fun>
val map_n_tree : ('a -> 'b) -> 'a n_tree -> 'b n_tree = <fun>

Upvotes: 2

Related Questions