* [Caml-list] Returning printf from a function
@ 2018-08-23 9:15 Richard W.M. Jones
2018-08-23 9:28 ` Florian Angeletti
0 siblings, 1 reply; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23 9:15 UTC (permalink / raw)
To: caml-list
This is a problem we hit from time to time and I don't think I've ever
really understood why it happens. This made up example shows the
essence:
----------------------------------------------------------------------
let get_printer out =
if out then Printf.printf else Printf.fprintf stderr
let () =
let printer = get_printer true in
printer "hello\n";
printer "goodbye %s\n" "everyone" (* line 7 *)
----------------------------------------------------------------------
$ ocamlopt test2.ml
File "test2.ml", line 7, characters 2-9:
Error: This function has type (unit, out_channel, unit) format -> unit
It is applied to too many arguments; maybe you forgot a `;'.
Type inference in line 6 seems to overspecify the inferred type of
printer, so that we get the error on line 7.
Why? And how to fix it?
Rich.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Returning printf from a function
2018-08-23 9:15 [Caml-list] Returning printf from a function Richard W.M. Jones
@ 2018-08-23 9:28 ` Florian Angeletti
2018-08-23 9:48 ` Richard W.M. Jones
0 siblings, 1 reply; 5+ messages in thread
From: Florian Angeletti @ 2018-08-23 9:28 UTC (permalink / raw)
To: caml-list
This is the value restriction at work, you can avoid the issue by replacing
let printer = get_printer true in ...
where the type of printer is "Format.formatter -> ('_weak1,
Format.formatter, unit) format -> '_weak1", with
let printer x = get_printer true x in ...
− octachron.
On 23/08/2018 11:15, Richard W.M. Jones wrote:
> This is a problem we hit from time to time and I don't think I've ever
> really understood why it happens. This made up example shows the
> essence:
>
> ----------------------------------------------------------------------
> let get_printer out =
> if out then Printf.printf else Printf.fprintf stderr
>
> let () =
> let printer = get_printer true in
> printer "hello\n";
> printer "goodbye %s\n" "everyone" (* line 7 *)
> ----------------------------------------------------------------------
>
> $ ocamlopt test2.ml
> File "test2.ml", line 7, characters 2-9:
> Error: This function has type (unit, out_channel, unit) format -> unit
> It is applied to too many arguments; maybe you forgot a `;'.
>
> Type inference in line 6 seems to overspecify the inferred type of
> printer, so that we get the error on line 7.
>
> Why? And how to fix it?
>
> Rich.
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Returning printf from a function
2018-08-23 9:28 ` Florian Angeletti
@ 2018-08-23 9:48 ` Richard W.M. Jones
2018-08-23 10:08 ` Florian Angeletti
0 siblings, 1 reply; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23 9:48 UTC (permalink / raw)
To: Florian Angeletti; +Cc: caml-list
Let's complicate this a bit further. The nearly exact code we are
having problems with is (note that give_fn can return None in the real
code):
----------------------------------------------------------------------
open Printf
let debug fs =
ksprintf print_endline fs
let give_fn () =
Some debug
let () =
let param = "x" in
debug "single";
debug "param: %s" param;
(match give_fn () with
| None -> ()
| Some fn ->
fn "fn";
fn "fn param: %s" param
);
()
----------------------------------------------------------------------
In this case there's no apparent way to add the extra parameter, I
don't think ...
Rich.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Returning printf from a function
2018-08-23 9:48 ` Richard W.M. Jones
@ 2018-08-23 10:08 ` Florian Angeletti
2018-08-23 10:23 ` Richard W.M. Jones
0 siblings, 1 reply; 5+ messages in thread
From: Florian Angeletti @ 2018-08-23 10:08 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 388 bytes --]
A solution that works in this specific example and does not require to
rewire the logic is
to return the printing function inside a record with the right universal
quantification:
...
type debug = {fn: 'a. ('a, unit, string, unit) format4 -> 'a }[@@unboxed];;
let udebug = {fn=debug}
let give_fn () = Some udebug
...
| Some {fn} ->
fn "fn";
fn "fn param: %s" param
[-- Attachment #2: Type: text/html, Size: 1163 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Returning printf from a function
2018-08-23 10:08 ` Florian Angeletti
@ 2018-08-23 10:23 ` Richard W.M. Jones
0 siblings, 0 replies; 5+ messages in thread
From: Richard W.M. Jones @ 2018-08-23 10:23 UTC (permalink / raw)
To: Florian Angeletti; +Cc: caml-list
On Thu, Aug 23, 2018 at 12:08:10PM +0200, Florian Angeletti wrote:
> A solution that works in this specific example and does not require to
> rewire the logic is
> to return the printing function inside a record with the right universal
> quantification:
>
> ...
>
> type debug = {fn: 'a. ('a, unit, string, unit) format4 -> 'a }[@@unboxed];;
>
> let udebug = {fn=debug}
>
> let give_fn () = Some udebug
>
> ...
>
> | Some {fn} ->
> fn "fn";
> fn "fn param: %s" param
Thanks, that does indeed work.
Rich.
--
Richard Jones
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-08-23 10:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-23 9:15 [Caml-list] Returning printf from a function Richard W.M. Jones
2018-08-23 9:28 ` Florian Angeletti
2018-08-23 9:48 ` Richard W.M. Jones
2018-08-23 10:08 ` Florian Angeletti
2018-08-23 10:23 ` Richard W.M. Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox