From: "Carette, Jacques" <carette@mcmaster.ca>
To: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
Cc: OCaML List Mailing <caml-list@inria.fr>
Subject: RE: [Caml-list] Option to fully expand types in error messages?
Date: Fri, 3 Jun 2016 15:42:22 +0000 [thread overview]
Message-ID: <F7B18907EEED5244A3608C61DF32A4E410D5B39A@FHSDB2D11-2.csu.mcmaster.ca> (raw)
In-Reply-To: <AD235CA6-F7A5-4CD0-AC81-161921DC51E3@math.nagoya-u.ac.jp>
[-- Attachment #1: Type: text/plain, Size: 2875 bytes --]
So here is an actual example. The error I get is
ocamlc -short-paths -c reproduce.ml
File "reproduce.ml", line 148, characters 21-25:
Error: Signature mismatch:
...
Values do not match:
val traverseexercise :
'a container PseudoCode.abstract ->
('a PseudoCode.abstract ->
'b PseudoCode.abstract -> ('c * 'b) PseudoCode.abstract) ->
'b PseudoCode.abstract ->
'd container ->
('d container -> 'c container PseudoCode.abstract -> 'e) -> 'e
is not included in
val traverseexercise :
loopdata container PseudoCode.abstract ->
(loopdata PseudoCode.abstract ->
loopdata PseudoCode.abstract ->
(loopdata * loopdata) PseudoCode.abstract) ->
loopdata PseudoCode.abstract ->
(< answer : 'a; state : 'b; .. >, loopdata) PseudoCode.cmonad
File "reproduce.ml", line 111, characters 6-206: Expected declaration
File "reproduce.ml", line 125, characters 8-24: Actual declaration
I can't tell from the above error what the actual cause is. The full code is attached. [This code is quite reduced already. It is kept at this size to show in more detail the kinds of errors we're seeing.]
Any 'hint' from OCaml as to the precise nature of the non-match would sure be appreciated.
Jacques
________________________________________
From: Jacques Garrigue [garrigue@math.nagoya-u.ac.jp]
Sent: June 2, 2016 19:59
To: Carette, Jacques
Cc: OCaML List Mailing
Subject: Re: [Caml-list] Option to fully expand types in error messages?
On 2016/06/03 04:18, "Carette, Jacques" wrote:
>
> In writing some code which uses a lot of monads with underlying types which use constraints, even simple errors can lead to extremely hard to read error messages. The main reason is that the two types given in errors are partially expanded, to different levels. This frequently means that the part where the type checker detects a mismatch is (extremely) opaque to human eyes.
>
> In that case, it would actually be preferable to fully expand the types. Yes, that will produce wallpaper. But at least the mismatch should be considerably easier to catch.
>
> Does this already exist, or should I submit a feature request?
>
> Jacques
In the error message, types are expanded just enough to get down to the conflict.
If the conflict is not visible at that point, this is probably a scoping error (and there should be an extra line stating that);
otherwise this should be seen as a bug.
As Yaron pointed, -short-paths can help by at least giving a normal form for paths (which may not be the expansion, but should be unique in the error context). But it will not expand a type if the expansion is not a type constructor, or if the parameters are different.
Jacques
[-- Attachment #2: reproduce.ml --]
[-- Type: application/octet-stream, Size: 4358 bytes --]
type ('p,'v) monad = 's -> ('s -> 'v -> 'w) -> 'w
constraint 'p = <state : 's; answer : 'w; ..>
let ret (a :'v) : ('p,'v) monad = fun s k -> k s a
let (let!) (m : ('p,'v) monad) (f : 'v -> ('p,'u) monad) : ('p,'u) monad
= fun s k -> m s (fun s' b -> f b s' k)
let k0 _ v = v
module type T = sig
type 'b abstract
type ('pc,'p) cmonad_constraint = unit
constraint
'p = <state : 's list; answer : 'w abstract>
constraint
'pc = <answer : 'w; state : 's; ..>
type ('pc,'v) cmonad = ('p, 'v abstract) monad
constraint _ = ('pc,'p) cmonad_constraint
val genrecloop :
(('b -> 'c) abstract ->
'b abstract -> 'd -> ('e -> 'c abstract -> 'c abstract) -> 'c abstract) ->
'b abstract -> 'd -> ('d -> 'c abstract -> 'g) -> 'g
val applyM :
('b -> 'c) abstract -> 'b abstract -> 'd -> ('d -> 'c abstract -> 'e) -> 'e
module Pair :
sig
val unpair : ('b * 'c) abstract -> 'b abstract * 'c abstract
end
module Idx :
sig
val zero : int abstract
val succ : int abstract -> int abstract
end
module Tuple :
sig
val tup2 : 'b abstract -> 'c abstract -> ('b * 'c) abstract
end
module CList :
sig
val nil : 'b list abstract
val cons : 'b abstract -> 'b list abstract -> 'b list abstract
val matchListM :
'b list abstract ->
('p, 'c) cmonad ->
('b abstract -> 'b list abstract -> ('p, 'c) cmonad) ->
('p, 'c) cmonad
end
end
module PseudoCode = struct
type 'b abstract = unit -> 'b
type ('pc,'p) cmonad_constraint = unit
constraint
'p = <state : 's list; answer : 'w abstract>
constraint
'pc = <answer : 'w; state : 's; ..>
type ('pc,'v) cmonad = ('p, 'v abstract) monad
constraint _ = ('pc,'p) cmonad_constraint
let genrecloop gen rtarg = fun s k -> k s
(fun () -> let rec loop j = gen (fun () -> loop) (fun () -> j) s k0 () in
loop (rtarg ()))
let apply f x = fun () -> (f ()) (x ())
let applyM f x = ret (apply f x)
module Pair = struct
(* To be able to deconstruct pairs in monadic code:
perform (a,b) <-- ret (unpair pv) *)
let unpair x = ((fun () -> fst (x ())), fun () -> snd (x ()))
let fst x = (fun () -> fst (x ()))
let snd x = (fun () -> snd (x ()))
end
module Idx = struct
let zero = fun () -> 0
let succ a = fun () -> (a ()) + 1
end
module Tuple = struct
let tup2 a b = fun () -> ( (a ()), (b ()) )
end
module CList = struct
let nil = fun () -> []
let cons a b = fun () -> (a ()) :: (b ())
let matchListM l empty nonempty = fun s k -> (fun () ->
match l () with
| [] -> empty s k ()
| h::t -> nonempty (fun () -> h) (fun () -> t) s k ())
end
end
module type Value = sig
type value
end
module IntV = struct
type value = int
end
module Traverse (CODE: T) = struct
open CODE
module ContainerLib (V:Value) (L:Value) = struct
module type Sig = sig
type value = V.value
type 'a container
type eltdesc
type loopdata = L.value
val traverseexercise :
value container abstract ->
(eltdesc abstract -> loopdata abstract -> (value * loopdata) abstract) ->
loopdata abstract ->
(* ('a, value container) cmonad *)
('a, value) cmonad
end
end
module ListContainerLib (V : Value) (L : Value) = struct
type value = V.value
type 'a container = 'a list
type eltdesc = value
type loopdata = L.value
let traverseexercise lst f data =
let gen self tup =
let (lst, i) = Pair.unpair tup in
CList.matchListM lst
(ret CList.nil)
(fun h t ->
let (v, i2) = Pair.unpair (f (h) i) in
let! r = (applyM self (Tuple.tup2 t i2)) in
ret (CList.cons v r))
in genrecloop gen (Tuple.tup2 lst data)
end
module Ex (Container : ContainerLib (IntV) (IntV).Sig) = struct
let traverseexercise container =
let body = fun _ n -> Tuple.tup2 n (Idx.succ n) in
Container.traverseexercise container body Idx.zero
end
end
module Test = struct
module TC = Traverse(PseudoCode)
module LCII = TC.ListContainerLib (IntV) (IntV)
module LT = TC.Ex (LCII)
end
next prev parent reply other threads:[~2016-06-03 15:42 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-02 19:18 Carette, Jacques
2016-06-02 19:44 ` Gabriel Scherer
2016-06-02 19:50 ` Yaron Minsky
2016-06-02 21:59 ` Carette, Jacques
2016-06-02 23:59 ` Jacques Garrigue
2016-06-03 15:42 ` Carette, Jacques [this message]
2016-06-03 15:50 ` Yaron Minsky
2016-06-04 6:27 ` Jacques Garrigue
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=F7B18907EEED5244A3608C61DF32A4E410D5B39A@FHSDB2D11-2.csu.mcmaster.ca \
--to=carette@mcmaster.ca \
--cc=caml-list@inria.fr \
--cc=garrigue@math.nagoya-u.ac.jp \
/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