    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Implementing Type-Classes as OCaml Modules</title>
        <link>https://members.accu.org/index.php/articles/2445</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #142 - December 2017</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c380/">o142</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-380/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+380/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Implementing Type-Classes as OCaml Modules</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 03 December 2017 22:27:28 +00:00 or Sun, 03 December 2017 22:27:28 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Type classes achieve overloading in functional paradigms. Shayne Fletcher implements some as OCaml modules.</p>
<p><strong>Body:</strong>&nbsp;<h2>Modular type classes</h2>

<p>In this article, we revisit the idea of type-classes first explored in a previous blog post [<a href="#[Fletcher16a]">Fletcher16a</a>]. This time though, the implementation technique will be by via OCaml modules inspired by the paper â€˜Modular Type Classesâ€™ [<a href="#[Dreyer07]">Dreyer07</a>] by Dreyer <em>et al</em>.</p>

<table class="sidebartable">
	<tr>
		<td class="title">Ad hoc polymorphism</td>
	</tr>
	<tr>
		<td>
			<table class="journaltable">
				<tr>
					<td>
						<p>In programming languages, there is a particular kind of polymorphism known formally called ad hoc polymorphism but better known as overloading. For example with overloading, an operator like + may be defined that works for many different kinds of numbers.</p>
						<p>In the programming language Haskell, a language construction called <em>type classes</em> provides a structured way to provide for ad hoc polymorphism. The OCaml programming language does not have type
classes but rather provides a construction called modules. Ad hoc polymorphism via Haskell-like typeclass style programming can be supported in OCaml by viewing type classes as a particular mode of use of modules. Indeed, the module approach can be argued as better in the sense that programmers can have explicit control over which type class
instances are available in a given scope.</p>
					</td>
				</tr>
			</table>
		</td>
	</tr>
</table>

<p>Starting with the basics, consider the class of types whose values can be compared for equality. Call this type-class <code>Eq</code>. We represent the class as a module signature.</p>

<pre class="programlisting">
  module type EQ = sig
    type t
    val eq : t * t â†’ bool
  end</pre>
  
<p>Specific instances of <code>Eq</code> are modules that implement this signature. Here are two examples.</p>

<pre class="programlisting">
  module Eq_bool : EQ with type t = bool = struct
    type t = bool
    let eq (a, b) = a = b
  end
  module Eq_int : EQ with type t = int = struct
    type t = int
    let eq (a, b) = a = b
  end</pre>
  
<p>Given instances of class <code>Eq</code> (<code>X</code> and <code>Y</code> say,) we realize that products of those instances are also in <code>Eq</code>. This idea can be expressed as a functor with the following type.</p>

<pre class="programlisting">
  module type EQ_PROD =
    functor (X : EQ) (Y : EQ) â†’ 
      EQ with type t = X.t * Y.t</pre>
	  
<p>The implementation of this functor is simply stated as the following.</p>

<pre class="programlisting">
  module Eq_prod : EQ_PROD =
    functor (X : EQ) (Y : EQ) â†’ struct
      type t = X.t * Y.t
      let eq ((x1, y1), (x2, y2)) 
        = X.eq (x1, x2) &amp;&amp; Y.eq(y1, y2)
  end</pre>
  
<p>With this functor we can build concrete instances for products. Hereâ€˜s one example.</p>

<pre class="programlisting">
  module Eq_bool_int : 
    EQ with type t = (bool * int) 
      = Eq_prod (Eq_bool) (Eq_int)</pre>
	  
<p>The class <code>Eq</code> can be used as a building block for the construction of new type classes. For example, we might define a new type-class <code>Ord</code> that admits types that are equality comparable and whose values can be ordered with a â€˜less-thanâ€™ relation. We introduce a new module type to describe this class.</p>

<pre class="programlisting">
  module type ORD = sig
    include EQ
    val lt : t * t â†’ bool
  end</pre>
  
<p>Hereâ€™s an example instance of this class.</p>

<pre class="programlisting">
  module Ord_int : ORD with type t = int = struct
    include Eq_int
    let lt (x, y) = Pervasives.( &lt; ) x y
  end</pre>
  
<p>As before, given two instances of this class, we observe that products of these instances also reside in the class. Accordingly, we have this functor type</p>

<pre class="programlisting">
  module type ORD_PROD =
    functor (X : ORD) (Y : ORD) â†’ ORD with type t 
      = X.t * Y.t</pre>
	  
<p>with the following implementation.</p>

<pre class="programlisting">
  module Ord_prod : ORD_PROD =
    functor (X : ORD) (Y : ORD) â†’ struct
      include Eq_prod (X) (Y)
      let lt ((x1, y1), (x2, y2)) =
        X.lt (x1, x2) || X.eq (x1, x2) &amp;&amp; 
        Y.lt (y1, y2)
  end</pre>
  
<p>This is the corresponding instance for pairs of integers.</p>

<pre class="programlisting">
  module Ord_int_int = Ord_prod (Ord_int) (Ord_int)</pre>
  
<p>Hereâ€™s a simple usage example.</p>

<pre class="programlisting">
  let test_ord_int_int = 
    let x = (1, 2) and y = (1, 4) in
    assert ( not (Ord_int_int.eq (x, y)) &amp;&amp; 
      Ord_int_int.lt (x, y))</pre>

<h2>Using type-classes to implement parametric polymorphism</h2>

<p>This section begins with the <code>Show</code> type-class.</p>

<pre class="programlisting">
  module type SHOW = sig
    type t
    val show : t â†’ string
  end</pre>
  
<p>In what follows, it is convenient to make an alias for module values of this type.</p>

<pre class="programlisting">
  type 'a show_impl = (module SHOW with type t = 'a)</pre>
  
<p>Here are two instances of this class...</p>

<pre class="programlisting">
  module Show_int : SHOW with type t = int = struct
    type t = int
    let show = Pervasives.string_of_int
  end
  module Show_bool : SHOW with type t = bool 
      = struct
    type t = bool
    let show = function | true â†’ &quot;True&quot; 
      | false â†’ &quot;False&quot;
  end</pre>
  
<p>...and here these instances are â€˜packedâ€™ as values:</p>

<pre class="programlisting">
  let show_int : int show_impl = 
    (module Show_int : SHOW with type t = int)
  let show_bool : bool show_impl = 
    (module Show_bool : SHOW with type t = bool)</pre>
	
<p>The existence of the <code>Show</code> class is all that is required to enable the writing of our first parametrically polymorphic function.</p>

<pre class="programlisting">
  let print : 'a show_impl â†’ 'a â†’ unit =
    fun (type a) (show : a show_impl) (x : a) â†’
    let module Show = 
      (val show : SHOW with type t = a) in
    print_endline@@ Show.show x
  let test_print_1 : unit = print show_bool true
  let test_print_2 : unit = print show_int 3</pre>
  
<p>The function <code>print</code> can be used with values of any type <code>'a</code> as long as the caller can produce evidence of <code>'a</code>â€™s membership in <code>Show</code> (in the form of a compatible instance).</p>

<p>Listing 1 begins with the definition of a type-class <code>Num</code> (the class of additive numbers) together with some example instances.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
module type NUM = sig
  type t
  val from_int : int â†’ t
  val ( + ) : t â†’ t â†’ t
end

type 'a num_impl = (module NUM with type t = 'a)

module Num_int : NUM with type t = int = struct
  type t = int
  let from_int x = x
  let ( + ) = Pervasives.( + )
end
    
let num_int = (module Num_int : NUM with 
  type t = int)

module Num_bool : NUM with type t = bool = struct
  type t = bool

  let from_int = function | 0 â†’ false 
    | _ â†’ true
  let ( + ) = function | true â†’ fun _ â†’ true 
    | false â†’ fun x â†’ x
end
  
let num_bool = 
  (module Num_bool : NUM with type t = bool)
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>The existence of <code>Num</code> admits writing a polymorphic function <code>sum</code> that will work for any <code>'a list</code> of values if only <code>'a</code> can be shown to be in <code>Num</code>.</p>

<pre class="programlisting">
  let sum : 'a num_impl â†’ 'a list â†’ 'a =
    fun (type a) (num : a num_impl) (ls : a list) â†’
      let module Num = 
        (val num : NUM with type t = a) in
      List.fold_right Num.( + ) ls (Num.from_int 0)
  let test_sum = sum num_int [1; 2; 3; 4]</pre>
  
<p>This next function requires evidence of membership in two classes.</p>

<pre class="programlisting">
  let print_incr : ('a show_impl * 'a num_impl)
      â†’ 'a â†’ unit =
    fun (type a) ((show : a show_impl),
      (num : a num_impl)) (x : a) â†’
      let module Num = 
        (val num : NUM with type t = a) in
      let open Num
      in print show (x + from_int 1)
  (*An instantiation*)
  let print_incr_int (x : int) : unit 
    = print_incr (show_int, num_int) x</pre>
	
<p>If <code>'a</code> is in <code>Show</code> then we can easily extend <code>Show</code> to include the type <code>'a list</code>. As we saw earlier, this kind of thing can be done with an appropriate functor. (See Listing 2.)</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
module type LIST_SHOW =
  functor (X : SHOW) â†’ 
    SHOW with type t = X.t list

  module List_show : LIST_SHOW =
    functor (X : SHOW) â†’ struct
      type t = X.t list
    
      let show =
        fun xs â†’
          let rec go first = function
            | [] â†’ &quot;]&quot;
            | h :: t â†’
              (if (first) then &quot;&quot; else &quot;, &quot;) 
               ^ X.show h ^ go false t 
          in &quot;[&quot; ^ go true xs
    end
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>There is also another way: one can write a function to dynamically compute an <code>'a list</code> <code>show_impl</code> from an <code>'a show_impl</code> (see Listing 3).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
let show_list : 'a show_impl â†’ 'a list show_impl
   = fun (type a) (show : a show_impl) â†’
    let module Show = 
      (val show : SHOW with type t = a) in
    (module struct
      type t = a list
      let show : t â†’ string =
        fun xs â†’
          let rec go first = function
            | [] â†’ &quot;]&quot;
            | h :: t â†’
              (if (first) then &quot;&quot; else &quot;, &quot;) 
                 ^ Show.show h ^ go false t
          in &quot;[&quot; ^ go true xs
    end : SHOW with type t = a list)

let testls : string = let module Show =
  (val (show_list show_int) 
  : SHOW with type t = int list) in
  Show.show (1 :: 2 :: 3 :: [])
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>The type-class <code>Mul</code> is an aggregation of the type-classes <code>Eq</code> and <code>Num</code> together with a function to perform multiplication. (Listing 4.)</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
module type MUL = sig
  include EQ
  include NUM with type t := t

  val mul : t â†’ t â†’ t
end

type 'a mul_impl = (module MUL with type t = 'a)

module type MUL_F =
   functor (E : EQ) (N : NUM with type t = E.t) 
   â†’ MUL with type t = E.t
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<p>A default instance of <code>Mul</code> can be provided given compatible instances of <code>Eq</code> and <code>Num</code>. (See Listing 5.)</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
module Mul_default : MUL_F =
  functor (E : EQ) (N : NUM with type t = E.t)  
      â†’ struct
    include (E : EQ with type t = E.t)
    include (N : NUM with type t := E.t)

    let mul : t â†’ t â†’ t =
      let rec loop x y = begin match () with
         | () when eq (x, (from_int 0)) 
           â†’ from_int 0
         | () when eq (x, (from_int 1)) â†’ y
         | () â†’ y + loop (x + (from_int (-1))) y
       end in loop
end

module Mul_bool : MUL with type t = bool = 
  Mul_default (Eq_bool) (Num_bool)   
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<p>Specific instances can be constructed as needs demand (Listing 6).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
module Mul_int : MUL with type t = int = struct
  include (Eq_int : EQ with type t = int)
  include (Num_int : NUM with type t := int)
  let mul = Pervasives.( * )
end
    
let dot : 'a mul_impl â†’ 'a list â†’ 'a list â†’ 'a
  = fun (type a) (mul : a mul_impl) â†’
    fun xs ys â†’
      let module M = 
        (val mul : MUL with type t = a) in
      sum (module M : NUM with type t = a)
        @@ List.map2 M.mul xs ys
let test_dot =
  dot (module Mul_int : MUL with type t = int) 
    [1; 2; 3] [4; 5; 6]
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<p>Note that in this definition of <code>dot</code>, coercion of the provided <code>Mul</code> instance to its base <code>Num</code> instance is performed.</p>
<p>Listing 7 provides an example of polymorphic recursion utilizing the dynamic production of evidence by way of the <code>show_list</code> function presented earlier.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
let rec replicate : int â†’ 'a â†’ 'a list =
  fun n x â†’ if n &lt;= 0 
    then [] else x :: replicate (n - 1) x
let rec print_nested : 'a. 'a show_impl â†’ 
  int â†’ 'a â†’ unit = fun show_mod â†’ function
  | 0 â†’ fun x â†’ print show_mod x
  | n â†’ fun x â†’ print_nested 
    (show_list show_mod) (n - 1) (replicate n x)
let test_nested =
  let n = read_int () in
  print_nested (module Show_int : SHOW 
  with type t = int) n 5
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 7</td>
	</tr>
</table>

<p class="EditorIntro">This article was previously published as a blog post in 2016. [<a href="#[Fletcher16b]">Fletcher16b</a>] and the source is available at: <a href="https://github.com/shayne-fletcher/overload-2017/blob/master/mod.ml">https://github.com/shayne-fletcher/overload-2017/blob/master/mod.ml</a></p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Dreyer07]"></a>[Dreyer07] Derek Dreyer, Robert Harper and Manuel M. T. Chakravarty, â€˜Modular Type Classesâ€™, 2007, available online at <a href="http://www.cse.unsw.edu.au/~chak/papers/mtc-popl.pdf">http://www.cse.unsw.edu.au/~chak/papers/mtc-popl.pdf</a></p>

<p class="bibliomixed"><a id="[Fletcher16a]"></a>[Fletcher16a] Shayne Fletcher, â€˜Haskell type-classes in OCaml and C++â€™, available at <a href="http://blog.shaynefletcher.org/2016/10/haskell-type-classes-in-ocaml-and-c.html">http://blog.shaynefletcher.org/2016/10/haskell-type-classes-in-ocaml-and-c.html</a></p>

<p class="bibliomixed"><a id="[Fletcher16b]"></a>[Fletcher16b] Shayne Fletcher, â€˜Implementing type-classes as OCaml modulesâ€™, available at <a href="http://blog.shaynefletcher.org/2016/10/implementing-type-classes-as-ocaml.html">http://blog.shaynefletcher.org/2016/10/implementing-type-classes-as-ocaml.html</a></p>

<p class="bibliomixed"><a id="[Kiselyov14]"></a>[Kiselyov14] Oleg Kiselyov, â€˜Implementing, and Understanding Type Classesâ€™, updated November 2014, available at <a href="http://okmij.org/ftp/Computation/typeclass.html">http://okmij.org/ftp/Computation/typeclass.html</a></p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
