| Newsgroups |
gmane.comp.lang.ocaml.beginners |
| Message-ID |
<CAPFanBFqenhK1JxxkdAiEk9A7im0so8ZNS4CiGxALdqyxX_zaA@mail.gmail.com> |
Signatures in OCaml have two purpose: they check compatibility, and
they enforce type abstract. They check, and they hide.
When you write
module Chargram : GRAMMAR = struct
...
end
you are enforcing the signature of Chargram to be GRAMMAR, and in
particular to have an *abstract* token type (this is a sealing
signature ascription). You could fix the type error by not enforcing a
signature there:
module Chargram = struct
...
end
This removes hiding. You can still check by doing it separately, with
for example:
let () = let module C : GRAMMAR = Chargram in ()
You can also use the GRAMMAR signature, but relaxed to have the
equality (type token = char), so that you hide a bit but keep what you
need:
module Chargram : (GRAMMAR with type token = char) = struct
...
end
Either change makes your example code type-check on my machine.
On Fri, Oct 2, 2015 at 11:49 PM, Hendrik Boom [email protected]
[ocaml_beginners] <[email protected]> wrote:
> On Wed, Sep 30, 2015 at 09:41:20PM +0200, Gabriel Scherer [email protected] [ocaml_beginners] wrote:
>> Could you provide a self-contained piece of code that fails to compile? It
>> is easier to debug such problems when we see the error source, and when it
>> is possible to experiment (check that a fix suggestion work) before sending
>> a reply. Note that you don't need to make it minimal.
>
> I made it minimal, and it no longer looks like what I wanted to do -- I
> managed to preserve the error while removing an entire module.
>
> But it still fails in the sme way:
>
> open Stream
>
> module type GRAMMAR =
> sig
> type token
> end;;
>
>
> module Chargram : GRAMMAR =
> struct
> type token = char;; (* Should really be a module's type parameter *)
> end;;
>
> let testx : Chargram.token Stream.t = Stream.of_string "str";;
>
>
> hendrik@notlookedfor:~/dv/parse/priority$ ocamlc ko1.ml
> File "ko1.ml", line 15, characters 38-60:
> Error: This expression has type char Stream.t
> but an expression was expected of type Chargram.token Stream.t
> Type char is not compatible with type Chargram.token
> hendrik@notlookedfor:~/dv/parse/priority$
>
>
>
> I want to use chargram in a way that requires that token = char.
>
> I also want to have other modules of type GRAMMAR with different types
> for token.
>
>
> -- hendrik
>
>
>
>>
>> On Wed, Sep 30, 2015 at 7:51 PM, Hendrik Boom [email protected]
>> [ocaml_beginners] <[email protected]> wrote:
>>
>> > My modules are hiding too much type information.
>> >
>> > I have a module that parses according to a grammar
>> > that is provided s a module parameter..
>> >
>> > The signature of the grammars involves several types
>> > relating to this grammar, such as the type of tokens
>> > produced by the lexer.
>> >
>> > module type GRAMMAR =
>> > sig
>> > type token
>> > type gramon = {symbol : token; next : gramon option; alt : gramon
>> > option;}
>> > type phrase
>> > ...
>> > ...
>> > end;;
>> >
>> >
>> > And a parser, that uses this grammar description:
>> >
>> >
>> > module Mixfix(Grammar : GRAMMAR) =
>> > struct
>> > ...
>> > ...
>> > let rec read
>> > (g : Grammar.gramon option)
>> > (prio : int)
>> > (input : Grammar.token Stream.t)
>> > (psf : Grammar.phrase list)
>> > (return : Grammar.phrase -> Grammar.token option ->
>> > Grammar.token Stream.t -> Grammar.phrase) =
>> > ...
>> > ...
>> > end
>> >
>> > In general there can be a lot of different types
>> > that act as tokens. But to test this parser, I define
>> > a specific grammar with token = char:
>> >
>> >
>> > module Chargram : GRAMMAR with token = char =
>> > struct
>> > type token = char;; (* Should really be a module's type parameter *)
>> > ...
>> > ...
>> > end;;
>> >
>> >
>> > and set up a test parser by giving Mixfix this grammar:
>> >
>> >
>> > module Test = Mixfix(Chargram);;
>> >
>> >
>> > Now this doesn't work because of information-hiding.
>> > Test.token is an abstract type. Even though in this
>> > case it *is* char, that information is not available
>> > when I call Test's functions outside the module, so
>> > the type check fails when I try to call Test.read with
>> > a char stream.
>> >
>> >
>> > So what is the *correct* way of providing this parametrization,
>> > so after specializing the module to char, I can call
>> > its functions knowing that Test.token is char, and the type check
>> > will succeed?
>> >
>> > Or should I be using some entirely different mechanism to
>> > accomplish my purpose?
>> >
>> > -- hendrik
>> >
>> >
>> >
>> >
>> >
>> >
>> > ------------------------------------
>> > Posted by: Hendrik Boom <[email protected]>
>> > ------------------------------------
>> >
>> > Archives up to December 31, 2011 are also downloadable at
>> > http://www.connettivo.net/cntprojects/ocaml_beginners
>> > The archives of the very official ocaml list (the seniors' one) can be
>> > found at http://caml.inria.fr
>> > Attachments are banned and you're asked to be polite, avoid flames etc.
>> > ------------------------------------
>> >
>> > Yahoo Groups Links
>> >
>> >
>> >
>> >
>
>
> ------------------------------------
> Posted by: Hendrik Boom <[email protected]>
> ------------------------------------
>
> Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
> The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
> Attachments are banned and you're asked to be polite, avoid flames etc.
> ------------------------------------
>
> Yahoo Groups Links
>
>
>