* Re: [Caml-list] Scanf and objects
2003-05-21 16:48 [Caml-list] Scanf and objects Christophe TROESTLER
@ 2003-05-21 18:42 ` Damien
0 siblings, 0 replies; 2+ messages in thread
From: Damien @ 2003-05-21 18:42 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 2460 bytes --]
On Wed, 21 May 2003 18:48:12 +0200 (CEST) Christophe TROESTLER wrote:
> Hi,
> [...]
> Now, is it possible to build objects through a format process? More
> precisely, I'd like to have a function that takes (something like) a
> format string, say "%i %f", and creates an object like
>
> object
> method fold : ('a -> int -> float -> 'a) -> 'a -> 'a
> end
>
> It does not look so easy to me since on one hand you would have to
> parametrize the object to be able to build its type incrementally
> (e.g. with a (int -> float -> 'a, 'a) type) but that would then forbid
> the fold method to be fully polymorphic (not really nice...). Is this
> correct? Are there workarounds?
it seems to me that's the same problem as
# let id x = x in id 5, id "1";;
- : int * string = (5, "1")
# let err id = id 3, id "3";;
Characters 20-23:
let err id = id 3, id "3";;
^^^
This expression has type string but is here used with type int
let's define the iterator :
# let mk ib fmt f =
let rec aux acc =
try aux (Scanf.bscanf ib fmt (f acc))
with End_of_file -> acc
in aux;;
val mk :
Scanf.Scanning.scanbuf ->
('a, Scanf.Scanning.scanbuf, 'b) format -> ('b -> 'a) -> 'b ->'b=<fun>
then use it :
# let buf() = Scanf.Scanning.from_string "3 4. 5 6. ";;
val buf : unit -> Scanf.Scanning.scanbuf = <fun>
# let fmt: (_,_,_) format = "%i %f " in
mk (buf()) fmt (fun acc i f -> float i +. f +. acc) 0.,
mk (buf()) fmt (fun acc i f -> i + (truncate f) + acc) 0;;
- : float * int = (18., 18)
# let err ib fmt f g = mk ib fmt f 0, mk ib fmt g "";;
Characters 48-50:
let err ib fmt f g = mk ib fmt f 0, mk ib fmt g "";;
^^
This expression has type string but is here used with type int
then when one try to turn it into an object, we get the same problem :
# class ['a] folder ib fmt = object
method fold : 'b. ('b -> 'a -> 'b) -> 'b -> 'b =
fun f -> mk ib fmt f
end;;
Characters 85-109:
This method has type ('a -> 'b -> 'a) -> 'a -> 'a which is less general
than 'c. ('c -> 'b -> 'c) -> 'c -> 'c
"fmt" beeing a parameter for the class "folder", he's not able to keep
its fully polymorphic type inside the class, and fails to have type
"('a->'b,_,'b) format" for all 'b
using a functor, I obtained the attached working code
but I'm not sure this will really be useful :
using the 'mk' function is far simpler...
damien
[-- Attachment #2: scanf.ml --]
[-- Type: application/octet-stream, Size: 569 bytes --]
module MK(M: sig type 'a t val fmt: ('a t,_,'a) format end) =
struct
class folder ib = object
method fold : 'b. ('b -> 'b M.t) -> 'b -> 'b =
fun f ->
let rec aux acc =
try aux (Scanf.bscanf ib M.fmt (f acc))
with End_of_file -> acc
in aux
end
end
;;
module F=MK(struct type 'a t = int -> float -> 'a let (fmt: ('a t,_,'a) format) = "%i %f " end)
;;
let buf() = Scanf.Scanning.from_string "3 4. 5 6. "
;;
let o = new F.folder (buf()) in
o#fold (fun acc i f -> float i +. f +. acc) 0.,
o#fold (fun acc i f -> i + (truncate f) + acc) 0
;;
^ permalink raw reply [flat|nested] 2+ messages in thread