caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: Caml List <caml-list@inria.fr>
Subject: Re: [Caml-list] How to write the fix data type
Date: Sun, 21 Oct 2012 09:53:48 +0200	[thread overview]
Message-ID: <CAPFanBGtZ0cHRk7OiS=4Ywz5-ySdr3OEfJOhdMQ+v_VtG_dhSw@mail.gmail.com> (raw)
In-Reply-To: <20121021043317.GA10985@romildo.no-ip.org>

There is a difficulty here because OCaml doesn't support higher-ranked
type variables. In this declaration, f is not a "type", but a "type
operator" (kind * -> *). To do the same in OCaml, you can use a
functor (not a Haskell functor; in OCaml the word "functor" denotes a
higher-order module that may depend on other modules/functors);
functors are higher-kinded.

    module type ParamType = sig
      type ('a, 'b) t
    end

    module Fix (M : ParamType) = struct
      type 'b fix = In of ('b fix, 'b) M.t
    end

    module List = struct
      module Param = struct
        type ('a, 'b) t = Nil | Cons of 'b * 'a
      end
      include Fix(Param)
    end

    open List.Param
    open List

    let rec to_usual_list =
      function
      | In Nil -> []
      | In (Cons (x, xs)) -> x :: to_usual_list xs

The good news is that OCaml also supports equi-recursive rather than
iso-recursive types, which allows you to remove the "In" wrapper at
each recursion layer. For that you must compile the incumbing module
(and all the modules that also see this equirecursion through an
interface) with the "-rectypes" option. Then you can write:

    module type ParamType = sig
      type ('a, 'b) t
    end

    module EqFix (M : ParamType) = struct
      type 'b fix = ('b fix, 'b) M.t
    end

    module EqList = struct
      module Param = struct
        type ('a, 'b) t = Nil | Cons of 'b * 'a
      end
      include EqFix(Param)
    end

    open EqList.Param

    let rec to_usual_list =
      function
      | Nil -> []
      | (Cons (x, xs)) -> x :: to_usual_list xs

The syntax of modules is quite heavy and could appear frightening. If
you insist you can use first-class modules to move some of these uses
from functors to simple functions. I choose to begin with the "simple"
way to do it first.

Higher-kinded variables envy is probably the most severe illness about
OCaml type worshippers (or Haskellers that for some (good!) reason
come to wander in these parts of Functional County). In practice we do
without it with not too much problems, but heavy use of monad
transformers would be complicated indeed by this functor step, which
is one of the reason it's not a very popular style around here.
You may also distract yourself by thinking about the imperfections of
higher-kinded variables in the languages that do support them; the
limitation to constructor polymorphism rather than arbitrary
type-level functions make them less expressive than you would like.
The day we work out the details of the absolutely perfect higher-order
type abstraction, maybe OCaml will jump to it?



On Sun, Oct 21, 2012 at 6:33 AM, José Romildo Malaquias
<j.romildo@gmail.com> wrote:
> Hello.
>
> How can I translate the following data type declaration from Haskell to
> OCaml?
>
>   newtype Fix f = In (f (Fix f))
>
>
> Romildo
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

      reply	other threads:[~2012-10-21  7:54 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-21  4:33 José Romildo Malaquias
2012-10-21  7:53 ` Gabriel Scherer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPFanBGtZ0cHRk7OiS=4Ywz5-ySdr3OEfJOhdMQ+v_VtG_dhSw@mail.gmail.com' \
    --to=gabriel.scherer@gmail.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).