<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2009/10/4ca654b611f32f152bdd91960b9dc571"
  from="Virgile Prevosto &lt;virgile.prevosto@m...&gt;"
  author="Virgile Prevosto"
  date="2009-10-09T08:22:27"
  subject="Re: [Caml-list] Why type inference fails in this code"
  prev="2009/10/bbdefe2c53d985fa64407ffd30ff459f"
  next="2009/10/5d9ee0d9aa8b4a42a068863184397ed1"
  prev-in-thread="2009/10/c46218099f9f865f3799bc41a7795d00"
  next-in-thread="2009/10/5d9ee0d9aa8b4a42a068863184397ed1"
  prev-thread="2009/10/16051196b9d9c0d5bf42b865d44384e1"
  next-thread="2009/10/0880e1b35fd2d07cead92a1871df73b7"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="Why type inference fails in this code">
<msg 
  url="2009/10/1b087dcc1f0f6132c02c68dbbb67bc95"
  from="rouanvd@s..."
  author="rouanvd@s..."
  date="2009-10-09T06:16:12"
  subject="Why type inference fails in this code">
<msg 
  url="2009/10/f3456671bdcf081d57adc3a920f0e8c4"
  from="Vincent Aravantinos &lt;vincent.aravantinos@g...&gt;"
  author="Vincent Aravantinos"
  date="2009-10-09T06:55:05"
  subject="Re: [Caml-list] Why type inference fails in this code">
</msg>
<msg 
  url="2009/10/c46218099f9f865f3799bc41a7795d00"
  from="Gabriel Kerneis &lt;kerneis@p...&gt;"
  author="Gabriel Kerneis"
  date="2009-10-09T07:09:38"
  subject="Re: [Caml-list] Why type inference fails in this code">
<msg 
  url="2009/10/4ca654b611f32f152bdd91960b9dc571"
  from="Virgile Prevosto &lt;virgile.prevosto@m...&gt;"
  author="Virgile Prevosto"
  date="2009-10-09T08:22:27"
  subject="Re: [Caml-list] Why type inference fails in this code">
<msg 
  url="2009/10/5d9ee0d9aa8b4a42a068863184397ed1"
  from="Gabriel Kerneis &lt;kerneis@p...&gt;"
  author="Gabriel Kerneis"
  date="2009-10-09T08:41:38"
  subject="Re: [Caml-list] Why type inference fails in this code">
<msg 
  url="2009/10/5c96f1a40514c135879a94830d6a6998"
  from="Gabriel Kerneis &lt;kerneis@p...&gt;"
  author="Gabriel Kerneis"
  date="2009-10-09T08:59:17"
  subject="Re: [Caml-list] Why type inference fails in this code">
</msg>
</msg>
</msg>
</msg>
<msg 
  url="2009/10/9506deb4a1f605c5972917617848927b"
  from="Jeremy Yallop &lt;yallop@g...&gt;"
  author="Jeremy Yallop"
  date="2009-10-09T10:22:59"
  subject="Re: [Caml-list] Why type inference fails in this code">
</msg>
</msg>
</thread>

<contents>
Hello,

Le ven. 09 oct. 2009 09:09:35 CEST,
Gabriel Kerneis &lt;kerneis@pps.jussieu.fr&gt; a écrit :

&gt; On Fri, Oct 09, 2009 at 07:25:41AM +0200, rouanvd@softwarerealisations.com wrote:
&gt; &gt; ======================================================
&gt; &gt; type t = MyInt of int | MyFloat of float | MyString of string ;;
&gt; &gt; 
&gt; &gt; let foo printerf = function
&gt; &gt;   | MyInt i -&gt; printerf string_of_int i
&gt; &gt;   | MyFloat x -&gt; printerf string_of_float x
&gt; &gt;   | MyString s -&gt; printerf (fun x -&gt; x) s
&gt; &gt; ;;
&gt; &gt; ======================================================
&gt; 
&gt; Type-inference has nothing to do with it, it's the type system itself
&gt; which fails.
&gt; 
&gt; What is the type you would expect? I guess:
&gt; (forall 'a. ('a -&gt; string) -&gt; 'a -&gt; 'b) -&gt; t -&gt; 'b
&gt; 
&gt; This is impossible with Ocaml: you cannot have a universal quantifier,
&gt; type variables are existantially quantified.
&gt; 

Well, I'm afraid this the other way round: a polymorphic type in Ocaml
is implicitly universally quantified: (fun x-&gt;x : 'a -&gt; 'a) means the
identity function can be applied to an argument of any type, not that
there exists a type 'a on which you can apply it.
In addition, the desired type for printerf is indeed an existential
one (printerf: exists 'a. 'a -&gt; string -&gt; 'a -&gt; 'b): you don't want the
first argument to convert any type to a string, just the type of the
second argument.

A possible but very heavy solution would be to use functors and local
modules everywhere (I guess that Haskell's typeclasses would help here).

type t = MyInt of int | MyFloat of float | MyString of string ;;

module type Printerf=functor(A:sig type t val to_string: t -&gt; string
end) -&gt; sig val print: A.t -&gt; unit
end

module Foo(Printerf:Printerf) = struct
let foo = function
| MyInt i -&gt;
    let module M = Printerf(struct type t = int
                                   let to_string = string_of_int end)
    in M.print i
| MyFloat x -&gt;
    let module M = Printerf(struct type t = float
                                   let to_string = string_of_float end)
    in M.print x
| MyString s -&gt;
    let module M = Printerf(struct type t = string
                                   let to_string = fun x -&gt; x end)
    in M.print s
end
;;

but personally I'd do the same thing as you:
&gt; In you very specific case, though, I guess refactoring it is possible:
&gt; let foo printerf = function
&gt;   | MyInt i -&gt; printerf (string_of_int i)
&gt;   | MyFloat x -&gt; printerf (string_of_float x)
&gt;   | MyString s -&gt; printerf s
&gt; ;;

-- 
E tutto per oggi, a la prossima volta.
Virgile

</contents>

</message>

