Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Brian Rogoff <bpr@best.com>
To: caml-list@inria.fr
Subject: [Caml-list] A G'Caml question
Date: Tue, 19 Jun 2001 20:16:59 -0700 (PDT)	[thread overview]
Message-ID: <Pine.BSF.4.21.0106192012390.24429-100000@shell5.ba.best.com> (raw)

Hi,
    One of the important issues with overloading is whether one has 
to define a "generic" function all in one place or if you can build it up 
piecemeal from already existing generic functions. I played a bit, learned 
some things, and now I have some questions. 

I start with the obvious "plus" function, and extend it so that in 
concatenates strings. 

# generic plus = case
    int -> int -> int => (+)
  | float -> float -> float => (+.) ;;  
val plus : $a -> $a -> $a [ int -> int -> int 
                          | float -> float -> float  ] =
  <fun>
# plus 1 2;;
- : int = 3
# plus 1.0 2.0;;
- : float = 3
# plus "1" "2";;
This generic full instance is used with type string -> string -> string
 which is not its valid instance of 
$a -> $a -> $a [ int -> int -> int 
               | float -> float -> float  ]
# generic plus = case 
  string -> string -> string => (^) 
  | $a -> $a -> $a => plus ;;  
val plus : $a -> $a -> $a
  [ string -> string -> string 
  | $a -> $a -> $a && plus : $a -> $a -> $a  ] = <fun>
# plus 1 1;;
- : int = 2
# plus "1" "2.0";;
- : string = "12.0"

Cool, for some very simple cases, it we can incrementally build up a 
generic function from pieces. I think it's obvious that we'll get into 
trouble with recursive generics. 

# generic rec print = case 
  | int -> unit => print_int
  | string -> unit => print_string
  | $a list -> unit => 
      function [] -> ()
      |   x :: xs -> print x; print xs
  ;;            
  val print : $a -> unit
  [ int -> unit 
  | string -> unit 
  | $a list -> unit && print : $a -> unit && print : $a list -> unit  ] =
  <fun>
# print 23;;
23- : unit = ()
# print 23.0;;
This generic full instance is used with type float -> unit
 which is not its valid instance of 
$a -> unit
[ int -> unit 
| string -> unit 
| $a list -> unit && print : $a -> unit && print : $a list -> unit  ]

OK, lets try the same thing as before, 

# generic rec print = case float -> unit => print_float | $a -> unit =>
print;;
val print : $a -> unit
  [ float -> unit 
  | $a -> unit && print : $a -> unit  ] = <fun>

# print 1.0;;
1- : unit = ()
# print 1 (* infinite loop! *)

Well, that should be expected, since we try and print an int, which isn't
a float, so we try (from $a -> unit => print) to print, ad infinitum. Is
there a way out? If we try and rename print and call that, it still won't work, 
since we want a form of "open recursion" here: if I add a case for float I 
want to be able to print float lists. With the original print
reinstalled...

# let print' = print ;;
val print' : $a -> unit [ $a -> unit && print : $a -> unit  ] = <fun>
# generic rec print = case float -> unit => print_float | $a -> unit =>
print';;
val print : $a -> unit
  [ float -> unit 
  | $a -> unit && print' : $a -> unit  ] = <fun>
# print 1.0;;
1- : unit = ()
# print [1;2;3];;
123- : unit = ()
# print [1.0;2.0;3.0];; 
This generic full instance is used with type float list -> unit
 which is not its valid instance of 
$a -> unit [ float -> unit 
           | $a -> unit && print' : $a -> unit  ]

Is there some trick to build up recursive generics by parts? One thing 
to do is to break the recursive generic into a non-recursive generic
and a recursive function which applies the generic to the elements, 
but that feels like cheating. Maybe open recursion for generics would 
be desirable, so that I can add a new case and have the recursive call in 
an existing case call the new one? Yes, it's a half baked idea, but maybe 
a better cook can finish baking...

-- Brian



-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


             reply	other threads:[~2001-06-20  3:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-06-20  3:16 Brian Rogoff [this message]
2001-06-25 17:11 ` "Re: [Caml-list] A G'Caml question" + additional info Jun Furuse
2001-06-28  2:21   ` Patrick M Doane
2001-06-28  4:40     ` Brian Rogoff

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=Pine.BSF.4.21.0106192012390.24429-100000@shell5.ba.best.com \
    --to=bpr@best.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