caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Type issue
@ 2007-11-23  4:01 Jonathan T Bryant
  2007-11-23  8:26 ` [Caml-list] " Andrej Bauer
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Jonathan T Bryant @ 2007-11-23  4:01 UTC (permalink / raw)
  To: caml-list

List,

I don't understand the following typing:

# type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a

# let rec f t = match t with
      Cond (c,t,e) -> if f c then f t else f e
    | Value x -> x
  ;;
val f : bool t -> bool = <fun>

I don't understand why f isn't of type 'a t -> 'a.  I understand that f 
is applied to a bool t, but I would think that that would just be a 
particular instantiation of 'a, not enough to fully determine its type.

--Jonathan Bryant


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

* Re: [Caml-list] Type issue
  2007-11-23  4:01 Type issue Jonathan T Bryant
@ 2007-11-23  8:26 ` Andrej Bauer
  2007-11-23  9:27   ` Oliver Bandel
  2007-11-23  8:30 ` Florian Weimer
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Andrej Bauer @ 2007-11-23  8:26 UTC (permalink / raw)
  To: Jonathan T Bryant; +Cc: caml-list

Here's a simpler example:

# fun (g, x) -> (g true, g x) ;;
- : (bool -> 'a) * bool -> 'a * 'a = <fun>

Even though it looks like g could be of type 'b -> 'a, ocaml decides to 
go with bool only. I see this on the mailing list every once in a while, 
but I always forget the reasoning behind it.

If I had to guess, it's just a result of unification algorithm in type 
reconstruction (which, incidentally I thought in class 20 minutes 
ago...). Starting from

g : 'b -> 'a
x : 'c

we get these equations:

'b = bool    because true must have type 'b
'c = 'b      because x must have type 'b

And now we get 'b = 'c = bool, hence the result.

Andrej


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

* Re: [Caml-list] Type issue
  2007-11-23  4:01 Type issue Jonathan T Bryant
  2007-11-23  8:26 ` [Caml-list] " Andrej Bauer
@ 2007-11-23  8:30 ` Florian Weimer
  2007-11-23  9:14 ` Alain Frisch
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Florian Weimer @ 2007-11-23  8:30 UTC (permalink / raw)
  To: Jonathan T Bryant; +Cc: caml-list

* Jonathan T. Bryant:

> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
>
> # let rec f t = match t with
>       Cond (c,t,e) -> if f c then f t else f e
>     | Value x -> x
>   ;;
> val f : bool t -> bool = <fun>

# let rec g t = match t with
      Cond (c,t,e) -> if f c then g t else g e
    | Value x -> x
  ;;
    val g : 'a t -> 'a = <fun>

The return value of f can't be generalized 'a because it's constrained
to bool in the if expression.  This problem does not arise for g.


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

* Re: [Caml-list] Type issue
  2007-11-23  4:01 Type issue Jonathan T Bryant
  2007-11-23  8:26 ` [Caml-list] " Andrej Bauer
  2007-11-23  8:30 ` Florian Weimer
@ 2007-11-23  9:14 ` Alain Frisch
  2007-11-23 13:38   ` Arnaud Spiwack
  2007-11-23  9:33 ` Oliver Bandel
  2007-11-23 12:33 ` Angela Zhu
  4 siblings, 1 reply; 9+ messages in thread
From: Alain Frisch @ 2007-11-23  9:14 UTC (permalink / raw)
  To: Jonathan T Bryant; +Cc: caml-list

Jonathan T Bryant wrote:
> List,
> 
> I don't understand the following typing:
> 
> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
> 
> # let rec f t = match t with
>       Cond (c,t,e) -> if f c then f t else f e
>     | Value x -> x
>   ;;
> val f : bool t -> bool = <fun>

The type system does not infer polymorphic recursion: the type of a 
recursive function cannot be more general than any of its occurences 
within its body.

You can get around this limitation in various ways. E.g., with recursive 
modules:

module rec M : sig val f : 'a t -> 'a end =
   struct
     let rec f t = match t with
     | Cond (c,t,e) -> if M.f c then f t else f e
     | Value x -> x
   end

let f = M.f


-- Alain


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

* Re: [Caml-list] Type issue
  2007-11-23  8:26 ` [Caml-list] " Andrej Bauer
@ 2007-11-23  9:27   ` Oliver Bandel
  0 siblings, 0 replies; 9+ messages in thread
From: Oliver Bandel @ 2007-11-23  9:27 UTC (permalink / raw)
  To: Andrej.Bauer, Andrej Bauer; +Cc: Jonathan T Bryant, caml-list

Zitat von Andrej Bauer <Andrej.Bauer@fmf.uni-lj.si>:

> Here's a simpler example:
>
> # fun (g, x) -> (g true, g x) ;;
> - : (bool -> 'a) * bool -> 'a * 'a = <fun>
>
> Even though it looks like g could be of type 'b -> 'a, ocaml decides to
> go with bool only. I see this on the mailing list every once in a while,
> but I always forget the reasoning behind it.
[...]

g true  ===>  g is a function applied to a bool; result-type unspecified.

g x     ===> x is a bool, because g is a function that takes a bool-arg;
             g is explained above.

So, with the application "g true"
you already have fixed the type!

Jonathan's problem is very similar.

Ciao,
   Oliver


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

* Re: [Caml-list] Type issue
  2007-11-23  4:01 Type issue Jonathan T Bryant
                   ` (2 preceding siblings ...)
  2007-11-23  9:14 ` Alain Frisch
@ 2007-11-23  9:33 ` Oliver Bandel
  2007-11-23 12:33 ` Angela Zhu
  4 siblings, 0 replies; 9+ messages in thread
From: Oliver Bandel @ 2007-11-23  9:33 UTC (permalink / raw)
  To: caml-list

Zitat von Jonathan T Bryant <jtbryant@valdosta.edu>:

> List,
>
> I don't understand the following typing:
>
> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
>
> # let rec f t = match t with
>       Cond (c,t,e) -> if f c then f t else f e
[...]
                       if [bool] then [bool] else [bool]

You have fixed the type here, because you have coupled them
together.

Ciao,
   Oliver


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

* Re: [Caml-list] Type issue
  2007-11-23  4:01 Type issue Jonathan T Bryant
                   ` (3 preceding siblings ...)
  2007-11-23  9:33 ` Oliver Bandel
@ 2007-11-23 12:33 ` Angela Zhu
  4 siblings, 0 replies; 9+ messages in thread
From: Angela Zhu @ 2007-11-23 12:33 UTC (permalink / raw)
  To: Jonathan T Bryant; +Cc: caml-list

I think it is because you have
"if  f c then ... else ..."
     ---

this restrict "f c" must be bool, thus 'a is bool.


On Nov 22, 2007 10:01 PM, Jonathan T Bryant <jtbryant@valdosta.edu> wrote:
> List,
>
> I don't understand the following typing:
>
> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
>
> # let rec f t = match t with
>       Cond (c,t,e) -> if f c then f t else f e
>     | Value x -> x
>   ;;
> val f : bool t -> bool = <fun>
>
> I don't understand why f isn't of type 'a t -> 'a.  I understand that f
> is applied to a bool t, but I would think that that would just be a
> particular instantiation of 'a, not enough to fully determine its type.
>
> --Jonathan Bryant
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>



-- 
Regards,
Angela Zhu
------------------------------------------
Dept. of CS, Rice University
http://www.cs.rice.edu/~yz2/
------------------------------------------


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

* Re: [Caml-list] Type issue
  2007-11-23  9:14 ` Alain Frisch
@ 2007-11-23 13:38   ` Arnaud Spiwack
  2007-11-23 13:44     ` Vincent Aravantinos
  0 siblings, 1 reply; 9+ messages in thread
From: Arnaud Spiwack @ 2007-11-23 13:38 UTC (permalink / raw)
  To: Alain Frisch; +Cc: Jonathan T Bryant, caml-list

Alain Frisch a écrit :
> Jonathan T Bryant wrote:
>> List,
>>
>> I don't understand the following typing:
>>
>> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
>> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
>>
>> # let rec f t = match t with
>>       Cond (c,t,e) -> if f c then f t else f e
>>     | Value x -> x
>>   ;;
>> val f : bool t -> bool = <fun>
>
> The type system does not infer polymorphic recursion: the type of a 
> recursive function cannot be more general than any of its occurences 
> within its body.
>
> You can get around this limitation in various ways. E.g., with 
> recursive modules:
My personal favorite, without modules :

# type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;

let f_gen branch next t = match t with
      Cond (c,t,e) -> if branch c then next t else next e
    | Value x -> x
  ;;

let rec f_deep t = f_gen f_deep f_deep t;;

let rec f t = f_gen f_deep f t;;


type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
val f_gen : (bool t -> bool) -> ('a t -> 'a) -> 'a t -> 'a = <fun>
val f_deep : bool t -> bool = <fun>
val f : 'a t -> 'a = <fun> 


The pattern is rather generic (here we can do a bit better by replacing 
"next" by a recursive call to f_gen actually) :
 - you first write a generic version of your function where "recursive 
calls" are taken as arguments
 - you write a certain number of type-specialized function which are 
intended to be used as initial "recursive calls".
   They are themselves really recursive
 - you write your final function by using the type-specialized ones as 
"recursive calls"

Notice that the use of "recursive calls" in the above is justified since 
all these functions have precisely the same semantics (and almost the 
same behaviour once compiled). But if someone has a better vocabulary to 
describe this practice, I'd gladly adopt it, as I'm not really satisfied 
with it. (I use "continuations" as well, but it still not quite what we 
intend).


Arnaud


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

* Re: [Caml-list] Type issue
  2007-11-23 13:38   ` Arnaud Spiwack
@ 2007-11-23 13:44     ` Vincent Aravantinos
  0 siblings, 0 replies; 9+ messages in thread
From: Vincent Aravantinos @ 2007-11-23 13:44 UTC (permalink / raw)
  To: Arnaud Spiwack; +Cc: Alain Frisch, Jonathan T Bryant, caml-list


Le 23 nov. 07 à 14:38, Arnaud Spiwack a écrit :

> Alain Frisch a écrit :
>> Jonathan T Bryant wrote:
>>> List,
>>>
>>> I don't understand the following typing:
>>>
>>> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
>>> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
>>>
>>> # let rec f t = match t with
>>>       Cond (c,t,e) -> if f c then f t else f e
>>>     | Value x -> x
>>>   ;;
>>> val f : bool t -> bool = <fun>
>>
>> The type system does not infer polymorphic recursion: the type of  
>> a recursive function cannot be more general than any of its  
>> occurences within its body.
>>
>> You can get around this limitation in various ways. E.g., with  
>> recursive modules:
> My personal favorite, without modules :
>
> # type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a;;
>
> let f_gen branch next t = match t with
>      Cond (c,t,e) -> if branch c then next t else next e
>    | Value x -> x
>  ;;
>
> let rec f_deep t = f_gen f_deep f_deep t;;
>
> let rec f t = f_gen f_deep f t;;
>
>
> type 'a t = Cond of bool t * 'a t * 'a t | Value of 'a
> val f_gen : (bool t -> bool) -> ('a t -> 'a) -> 'a t -> 'a = <fun>
> val f_deep : bool t -> bool = <fun>
> val f : 'a t -> 'a = <fun>
>
> The pattern is rather generic (here we can do a bit better by  
> replacing "next" by a recursive call to f_gen actually) :
> - you first write a generic version of your function where  
> "recursive calls" are taken as arguments
> - you write a certain number of type-specialized function which are  
> intended to be used as initial "recursive calls".
>   They are themselves really recursive
> - you write your final function by using the type-specialized ones  
> as "recursive calls"
>
> Notice that the use of "recursive calls" in the above is justified  
> since all these functions have precisely the same semantics (and  
> almost the same behaviour once compiled). But if someone has a  
> better vocabulary to describe this practice, I'd gladly adopt it,  
> as I'm not really satisfied with it. (I use "continuations" as  
> well, but it still not quite what we intend).

This is just wonderful !

Thanks,
V.

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

end of thread, other threads:[~2007-11-23 13:44 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-23  4:01 Type issue Jonathan T Bryant
2007-11-23  8:26 ` [Caml-list] " Andrej Bauer
2007-11-23  9:27   ` Oliver Bandel
2007-11-23  8:30 ` Florian Weimer
2007-11-23  9:14 ` Alain Frisch
2007-11-23 13:38   ` Arnaud Spiwack
2007-11-23 13:44     ` Vincent Aravantinos
2007-11-23  9:33 ` Oliver Bandel
2007-11-23 12:33 ` Angela Zhu

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