* [Caml-list] Unifying buildt-in types with polymorphic types
@ 2014-05-15 19:24 Peter Frey
2014-05-15 20:28 ` Jeremy Yallop
0 siblings, 1 reply; 3+ messages in thread
From: Peter Frey @ 2014-05-15 19:24 UTC (permalink / raw)
To: caml-list
(* In the code below I have 3 fragments of streams, based on a cons
cell; another on an array and, finally, the third is based on a string.
I need all streams to have the same signature 'StreamOps'.
This works fine for a stream where 'a t is a true polymorphic
value but fails for module StmStr at the bottom of the code sample;
giving:
...
Values do not match:
val head : int * 'a cursor -> char
is not included in
val head : 'a t -> 'a
I don't know if I run afoul of a form of narrowing; or if this is some
sort of limitation with respect to unboxed types.
Any help would be greatly appreciated.
Peter Frey
*)
module type StreamOps = sig
type 'a t
val head : 'a t -> 'a
end
module LazyStream : StreamOps = struct
type 'a t = Cons of 'a * 'a t Lazy.t
let head (Cons (h, _)) = h
end
module StmLzy = (LazyStream:StreamOps with type 'a t = 'a LazyStream.t)
module MakeEltAry = functor(S:sig include module type of Array end) ->
struct
type 'a cursor = { ofs: int; lim: int; data: 'a array }
and 'a t = int * 'a cursor
let get s i = S.get s.data i
let head (i, s) = get s i
end
module EltAry = MakeEltAry(Array)
module StmAry = (EltAry:StreamOps with type 'a t = 'a EltAry.t)
module MakeEltStr = functor(S:sig include module type of String end) ->
struct
type 'a cursor = { ofs: int; lim: int; data: string }
and 'a t = int * 'a cursor
let get s i = S.get s.data i
let head (i, s) = get s i
end
module EltStr = MakeEltStr(String)
module StmStr = (EltStr:StreamOps with type 'a t = 'a EltStr.t)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] Unifying buildt-in types with polymorphic types
2014-05-15 19:24 [Caml-list] Unifying buildt-in types with polymorphic types Peter Frey
@ 2014-05-15 20:28 ` Jeremy Yallop
2014-05-16 21:41 ` Peter Frey
0 siblings, 1 reply; 3+ messages in thread
From: Jeremy Yallop @ 2014-05-15 20:28 UTC (permalink / raw)
To: Peter Frey; +Cc: Caml List
On 15 May 2014 20:24, Peter Frey <pjfrey@sympatico.ca> wrote:
> I need all streams to have the same signature 'StreamOps'.
It's not possible with the current definition of StreamOps. The
difficulty is that the stream type and the element type vary
non-uniformly in your various stream implementations:
StmLzy defines streams of type 'a t = Cons of 'a * 'a t Lazy.t
with elements of 'a
StmAry defines streams of type 'a t = int * 'a cursor
with elements of 'a
StmStr defines streams of type 'a t = int * 'a cursor
with elements of char
but the signature leaves only the stream type 'a t unspecified,
providing no way for the element type to vary in the implementation.
One solution is to change the StreamOps signature to include both the
element type and the stream type. Once you've added an element type
to the signature there's no need to parameterize the stream type:
module type StreamOps = sig
type elt (* the element type *)
type t (* the stream type *)
val head : t -> elt
end
The implementations of StreamOps then become functors over the element
type. This is the approach used in the standard library to define
maps and sets (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Set.Make.html).
For example, you might define LazyStream as follows
module LazyStream (E : sig type elt end)
: StreamOps with type elt = E.elt =
struct
type elt = E.elt
type t = Cons of elt * t Lazy.t
let head (Cons (h, _)) = h
end
The element type of StmStr doesn't vary, so there's no need to make it
a functor:
module StmStr : StreamOps with type elt = char =
struct
type elt = char
type cursor = { ofs: int; lim: int; data: string }
type t = int * cursor
let get s i = String.get s.data i
let head (i, s) = get s i
end
I hope that helps,
Jeremy.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] Unifying buildt-in types with polymorphic types
2014-05-15 20:28 ` Jeremy Yallop
@ 2014-05-16 21:41 ` Peter Frey
0 siblings, 0 replies; 3+ messages in thread
From: Peter Frey @ 2014-05-16 21:41 UTC (permalink / raw)
To: Jeremy Yallop; +Cc: Caml List
On Thu, 2014-05-15 at 21:28 +0100, Jeremy Yallop wrote:
> On 15 May 2014 20:24, Peter Frey <pjfrey@sympatico.ca> wrote:
> > I need all streams to have the same signature 'StreamOps'.
>
> It's not possible with the current definition of StreamOps. The
> difficulty is that the stream type and the element type vary
> non-uniformly in your various stream implementations:
>
> StmLzy defines streams of type 'a t = Cons of 'a * 'a t Lazy.t
> with elements of 'a
>
> StmAry defines streams of type 'a t = int * 'a cursor
> with elements of 'a
>
> StmStr defines streams of type 'a t = int * 'a cursor
> with elements of char
>
> but the signature leaves only the stream type 'a t unspecified,
> providing no way for the element type to vary in the implementation.
>
> One solution is to change the StreamOps signature to include both the
> element type and the stream type. Once you've added an element type
> to the signature there's no need to parameterize the stream type:
>
> module type StreamOps = sig
> type elt (* the element type *)
> type t (* the stream type *)
> val head : t -> elt
> end
>
> The implementations of StreamOps then become functors over the element
> type. This is the approach used in the standard library to define
> maps and sets (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Set.Make.html).
> For example, you might define LazyStream as follows
>
> module LazyStream (E : sig type elt end)
> : StreamOps with type elt = E.elt =
> struct
> type elt = E.elt
> type t = Cons of elt * t Lazy.t
> let head (Cons (h, _)) = h
> end
>
> The element type of StmStr doesn't vary, so there's no need to make it
> a functor:
>
> module StmStr : StreamOps with type elt = char =
> struct
> type elt = char
> type cursor = { ofs: int; lim: int; data: string }
> type t = int * cursor
> let get s i = String.get s.data i
> let head (i, s) = get s i
> end
>
> I hope that helps,
>
> Jeremy.
>
This helped a lot, thank you.
(Typing is hard; I have been programming since 1963 and always had a
clear idea what I was doing, because previous languages translated
statements into code; Assemblers (many) Cobol Fortran Snobol Prolog
Pascal Cs ... Now the type checker translates types into types...
perhaps I am getting to old...)
thanks again
Peter
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-16 21:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-15 19:24 [Caml-list] Unifying buildt-in types with polymorphic types Peter Frey
2014-05-15 20:28 ` Jeremy Yallop
2014-05-16 21:41 ` Peter Frey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox