Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001156OCamlOCaml generalpublic2002-05-17 14:252013-08-31 12:46
Reporteradministrator 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityalways
StatusclosedResolutionno change required 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0001156: ma fonction n'est pas assez polymorphe
Description        Objective Caml version 3.04
(Même chose avec la version 3.04+10 (2002-04-18))
   # #load "unix.cma";;
Soient ces 2 fonctions:
   # let read_string_bang ?(src=Unix.stdin) s = Unix.read src s 0 (String.length s);;
   val read_string_bang : ?src:Unix.file_descr -> string -> int = <fun>
   # let read_string_bang_in ?(src=stdin) s = input src s 0 (String.length s);;
   val read_string_bang_in : ?src:in_channel -> string -> int = <fun>
Je veux écrire ça:
   # let (read_string, read_string_in) =
     let read reader ?src nbytes =
       let s = String.create nbytes in
       let nread = reader ?src s in
       if nread = nbytes then s else String.sub s 0 nread
     in
     (read read_string_bang, read read_string_bang_in)
   ;;
   val read_string : ?src:Unix.file_descr -> int -> string = <fun>
   val read_string_in : ?src:in_channel -> int -> string = <fun>

Mais si je précise le type de reader, ça ne va plus:
   # let (read_string, read_string_in) =
       let read (reader : ?src: 'a -> string -> int) ?src nbytes =
     let s = String.create nbytes in
     let nread = reader ?src s in
     if nread = nbytes then s else String.sub s 0 nread
       in
       (read read_string_bang, read read_string_bang_in)
                    ^^^^^^^^^^^^^^^^^^^
     ;;
   This expression has type ?src:in_channel -> string -> int
   but is here used with type ?src:Unix.file_descr -> string -> int
Pourquoi ? (Je connais la règle mu, mais il n'y a pas de let rec ici).

Le problème est que read_string_bang/read_string_bang_in ont en
réalité 2 autres arguments optionnels, et que j'ai le choix entre:
   # let (read_string, read_string_in) =
     let read reader ?src nbytes =
       let s = String.create nbytes in
       let nread = reader ?src ?start:None ?endd:None s in
       if nread = nbytes then s else String.sub s 0 nread
     in
     (read read_string_bang, read read_string_bang_in)
   ;;
mais dans cette forme d'expression, les arguments optionnels ne le
sont plus du tout ?? et:
   # let (read_string, read_string_in) =
     let read (reader : ?src: 'a -> ?start -> ?endd -> string -> int) ?src nbytes =
       let s = String.create nbytes in
       let nread = reader ?src s in
       if nread = nbytes then s else String.sub s 0 nread
     in
     (read read_string_bang, read read_string_bang_in)
   ;;
qui ne passe pas.

Noter qu'extraire read en le rendant global dans ce dernier exemple
est accepté par le compilo (!).

Alors, bug or feature ?

Bruno.

TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0000125)
administrator (administrator)
2002-06-03 17:18

Behavior due to restrictive treatment of type variables in type constraints
(they are considered at "level 0", hence not generalizable at an inner "let").
Consider making them generalizable at the innermost "let" that encloses all of
their occurrences.
(0000126)
administrator (administrator)
2002-06-10 05:29

On peut aisement contourner le probleme des variables nommees pas assez
polymorphes en utilisant des variables de type anonymes:

   # let (read_string, read_string_in) =
       let read (reader : ?src: _ -> string -> int) ?src nbytes =
     let s = String.create nbytes in
     let nread = reader ?src s in
     if nread = nbytes then s else String.sub s 0 nread
       in
       (read read_string_bang, read read_string_bang_in)
     ;;

Donc le probleme n'est pas dramatique.

Jacques Garrigue
(0000127)
administrator (administrator)
2002-06-10 12:19

   Date: Mon, 10 Jun 2002 05:29:20 +0200 (MET DST)
   From: Jacques Garrigue <caml-bugs@pauillac.inria.fr>

   On peut aisement contourner le probleme des variables nommees pas
   assez polymorphes en utilisant des variables de type anonymes:
      # let (read_string, read_string_in) =
      let read (reader : ?src: _ -> string -> int) ?src nbytes =
        let s = String.create nbytes in
        let nread = reader ?src s in
        if nread = nbytes then s else String.sub s 0 nread
      in
      (read read_string_bang, read read_string_bang_in);;
Merci du truc.
    
   Donc le probleme n'est pas dramatique.
En effet, pragmatiquement, ça me va tout à fait. Mais je n'en avais
jamais vu d'exemple; est-ce documenté quelque part ?

Bruno.

(0006755)
doligez (administrator)
2012-01-20 14:32

Underscore as a type variable is documented here:
  http://caml.inria.fr/pub/docs/manual-ocaml/types.html [^]

The (implicit) binding of type variables in type constraints is not going to change anytime soon, as that would probably break some programs while providing very little improvement.


- Issue History
Date Modified Username Field Change
2005-11-18 10:13 administrator New Issue
2012-01-20 14:32 doligez Note Added: 0006755
2012-01-20 14:32 doligez Status acknowledged => resolved
2012-01-20 14:32 doligez Resolution open => no change required
2012-01-20 14:32 doligez Description Updated View Revisions
2013-08-31 12:46 xleroy Status resolved => closed


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker