Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ma fonction n'est pas assez polymorphe #3353

Closed
vicuna opened this issue May 17, 2002 · 4 comments
Closed

ma fonction n'est pas assez polymorphe #3353

vicuna opened this issue May 17, 2002 · 4 comments

Comments

@vicuna
Copy link

vicuna commented May 17, 2002

Original bug ID: 1156
Reporter: administrator
Status: closed (set by @xavierleroy on 2013-08-31T10:46:03Z)
Resolution: not a bug
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)
Monitored by: till

Bug 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 =

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 =
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 =
val read_string_in : ?src:in_channel -> int -> string =

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.

@vicuna
Copy link
Author

vicuna commented Jun 3, 2002

Comment author: administrator

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.

@vicuna
Copy link
Author

vicuna commented Jun 10, 2002

Comment author: administrator

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

@vicuna
Copy link
Author

vicuna commented Jun 10, 2002

Comment author: administrator

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.

@vicuna
Copy link
Author

vicuna commented Jan 20, 2012

Comment author: @damiendoligez

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant