caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] phantom type
@ 2015-04-27 10:23 Jiten Pathy
  2015-04-27 10:36 ` Jeremy Yallop
  0 siblings, 1 reply; 7+ messages in thread
From: Jiten Pathy @ 2015-04-27 10:23 UTC (permalink / raw)
  To: caml-list

Hello,
Trying to use phantom types instead of gadt for well-constructed term
example. Is it possible to define an evaluator eval : 'a term -> 'a
using phantom types? Something like following doesn't work.

type expr = Zero | Succ of expr | Iszero of expr;;
type 'a term = Expr of expr;;

(* ways to construct a term *)
let zero : int term = Expr Zero;;
let succ : int term -> int term = fun (Expr x) -> Expr (Succ x);;
let iszero : int term -> bool term = fun (Expr x) -> Expr (Iszero x);;

let rec eval : 'a.'a term -> 'a = fun (type a) (t : a term) -> match t with
| Expr Zero -> 0
| Expr (Succ e) -> eval (Expr e) + 1
| Expr (Iszero e) -> if (eval (Expr e) == 0) then true else false
;;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 10:23 [Caml-list] phantom type Jiten Pathy
@ 2015-04-27 10:36 ` Jeremy Yallop
  2015-04-27 11:32   ` Jiten Pathy
  2015-04-27 11:51   ` Stephen Dolan
  0 siblings, 2 replies; 7+ messages in thread
From: Jeremy Yallop @ 2015-04-27 10:36 UTC (permalink / raw)
  To: Jiten Pathy; +Cc: caml-list

On 27 April 2015 at 11:23, Jiten Pathy <jpathy@fssrv.net> wrote:
> Trying to use phantom types instead of gadt for well-constructed term
> example. Is it possible to define an evaluator eval : 'a term -> 'a
> using phantom types?

No, it's not really possible.  If the 'a parameter to 'term' is
phantom then 'term' is defined using some other unparameterised type
such as your 'expr':

> type expr = Zero | Succ of expr | Iszero of expr;;

and the problem comes down to writing a function of type

   expr -> 'a

which is clearly impossible.

Phantom types only really help with constraints on building or
transforming values, not with deconstructing them.

However, there are various ways of writing well-typed evaluators
without using GADTs, e.g.using a "final" encoding, which represents a
term as an evaluation function:

   Finally Tagless, Partially Evaluated:
   http://okmij.org/ftp/tagless-final/JFP.pdf

or by encoding GADTs using polymorphism:

   First-class modules: hidden power and tantalizing promises
   http://okmij.org/ftp/ML/first-class-modules/first-class-modules.pdf

Jeremy.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 10:36 ` Jeremy Yallop
@ 2015-04-27 11:32   ` Jiten Pathy
  2015-04-27 11:51   ` Stephen Dolan
  1 sibling, 0 replies; 7+ messages in thread
From: Jiten Pathy @ 2015-04-27 11:32 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: caml-list

Thanks for the reference.

On Mon, Apr 27, 2015 at 3:36 AM, Jeremy Yallop <yallop@gmail.com> wrote:
> On 27 April 2015 at 11:23, Jiten Pathy <jpathy@fssrv.net> wrote:
>> Trying to use phantom types instead of gadt for well-constructed term
>> example. Is it possible to define an evaluator eval : 'a term -> 'a
>> using phantom types?
>
> No, it's not really possible.  If the 'a parameter to 'term' is
> phantom then 'term' is defined using some other unparameterised type
> such as your 'expr':
>
>> type expr = Zero | Succ of expr | Iszero of expr;;
>
> and the problem comes down to writing a function of type
>
>    expr -> 'a
>
> which is clearly impossible.
>
> Phantom types only really help with constraints on building or
> transforming values, not with deconstructing them.
>
> However, there are various ways of writing well-typed evaluators
> without using GADTs, e.g.using a "final" encoding, which represents a
> term as an evaluation function:
>
>    Finally Tagless, Partially Evaluated:
>    http://okmij.org/ftp/tagless-final/JFP.pdf
>
> or by encoding GADTs using polymorphism:
>
>    First-class modules: hidden power and tantalizing promises
>    http://okmij.org/ftp/ML/first-class-modules/first-class-modules.pdf
>
> Jeremy.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 10:36 ` Jeremy Yallop
  2015-04-27 11:32   ` Jiten Pathy
@ 2015-04-27 11:51   ` Stephen Dolan
  2015-04-27 12:17     ` Jiten Pathy
  1 sibling, 1 reply; 7+ messages in thread
From: Stephen Dolan @ 2015-04-27 11:51 UTC (permalink / raw)
  To: Jiten Pathy; +Cc: Jeremy Yallop, caml-list

To expand a little on Jeremy's answer, you can encode the expr type as
a module signature, and then pass terms around as first-class modules.

First, you make a module signature that describes the ways of
constructing a term:

    module type Ctors = sig
      type 'a term
      val zero : int term
      val succ : int term -> int term
      val iszero : int term -> bool term
    end

Next, a Term is something which can construct a term using any set of Ctors:

    module type Term = sig
      type a
      module Build : functor (C : Ctors) -> sig
        val x : a C.term
      end
    end

You can make a normal datatype from this using first-class modules:

    type 'a term = (module Term with type a = 'a)

We're jumping between the module and the core language, so the
wrapping and unwrapping makes things a bit verbose. Here's the
value-level "succ" operation, the other two are similar:

    let succ ((module T) : int term) : int term =
      (module struct
        type a = int
        module Build = functor (C : Ctors) -> struct
          module TC = T.Build (C)
          let x = C.succ TC.x
        end
      end)

Evaluation is one particular implementation of the term constructors,
which implements the type 'a term as just 'a:

    module Eval = struct
      type 'a term = 'a
      let zero = 0
      let succ n = n + 1
      let iszero n = (n = 0)
    end

Finally, you can use this evaluation module to interpret any term:

let eval (type a) ((module T) : a term) : a =
  let module M = T.Build (Eval) in M.x

Stephen

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 11:51   ` Stephen Dolan
@ 2015-04-27 12:17     ` Jiten Pathy
  2015-04-27 12:30       ` Jeremy Yallop
  0 siblings, 1 reply; 7+ messages in thread
From: Jiten Pathy @ 2015-04-27 12:17 UTC (permalink / raw)
  To: Stephen Dolan; +Cc: Jeremy Yallop, caml-list

It seems this encoding using first-class modules has overheads in the
interpreter(due to the functor), whereas the gadt implementation would
have no overheads.

On Mon, Apr 27, 2015 at 4:51 AM, Stephen Dolan
<stephen.dolan@cl.cam.ac.uk> wrote:
> To expand a little on Jeremy's answer, you can encode the expr type as
> a module signature, and then pass terms around as first-class modules.
>
> First, you make a module signature that describes the ways of
> constructing a term:
>
>     module type Ctors = sig
>       type 'a term
>       val zero : int term
>       val succ : int term -> int term
>       val iszero : int term -> bool term
>     end
>
> Next, a Term is something which can construct a term using any set of Ctors:
>
>     module type Term = sig
>       type a
>       module Build : functor (C : Ctors) -> sig
>         val x : a C.term
>       end
>     end
>
> You can make a normal datatype from this using first-class modules:
>
>     type 'a term = (module Term with type a = 'a)
>
> We're jumping between the module and the core language, so the
> wrapping and unwrapping makes things a bit verbose. Here's the
> value-level "succ" operation, the other two are similar:
>
>     let succ ((module T) : int term) : int term =
>       (module struct
>         type a = int
>         module Build = functor (C : Ctors) -> struct
>           module TC = T.Build (C)
>           let x = C.succ TC.x
>         end
>       end)
>
> Evaluation is one particular implementation of the term constructors,
> which implements the type 'a term as just 'a:
>
>     module Eval = struct
>       type 'a term = 'a
>       let zero = 0
>       let succ n = n + 1
>       let iszero n = (n = 0)
>     end
>
> Finally, you can use this evaluation module to interpret any term:
>
> let eval (type a) ((module T) : a term) : a =
>   let module M = T.Build (Eval) in M.x
>
> Stephen

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 12:17     ` Jiten Pathy
@ 2015-04-27 12:30       ` Jeremy Yallop
  2015-04-28  4:35         ` Jiten Pathy
  0 siblings, 1 reply; 7+ messages in thread
From: Jeremy Yallop @ 2015-04-27 12:30 UTC (permalink / raw)
  To: Jiten Pathy; +Cc: Stephen Dolan, caml-list

On 27 April 2015 at 13:17, Jiten Pathy <jpathy@fssrv.net> wrote:
> It seems this encoding using first-class modules has overheads in the
> interpreter(due to the functor), whereas the gadt implementation would
> have no overheads.

Have you measured it?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Caml-list] phantom type
  2015-04-27 12:30       ` Jeremy Yallop
@ 2015-04-28  4:35         ` Jiten Pathy
  0 siblings, 0 replies; 7+ messages in thread
From: Jiten Pathy @ 2015-04-28  4:35 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: Stephen Dolan, caml-list

No, it was just a speculation as a new record is created for every
sub-term evaluation.

On Mon, Apr 27, 2015 at 5:30 AM, Jeremy Yallop <yallop@gmail.com> wrote:
> On 27 April 2015 at 13:17, Jiten Pathy <jpathy@fssrv.net> wrote:
>> It seems this encoding using first-class modules has overheads in the
>> interpreter(due to the functor), whereas the gadt implementation would
>> have no overheads.
>
> Have you measured it?

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-04-28  4:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-27 10:23 [Caml-list] phantom type Jiten Pathy
2015-04-27 10:36 ` Jeremy Yallop
2015-04-27 11:32   ` Jiten Pathy
2015-04-27 11:51   ` Stephen Dolan
2015-04-27 12:17     ` Jiten Pathy
2015-04-27 12:30       ` Jeremy Yallop
2015-04-28  4:35         ` Jiten Pathy

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).