Version française
Home     About     Download     Resources     Contact us    
Browse thread
killing a cat
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Zheng Li <zheng_li@u...>
Subject: Re: killing a cat
Hi,

Warren Harris wrote:
> Now, I could get around this by making "f" be a function that when 
> evaluated returns the result of the helper. However, I'm trying to 
> avoid that because in the real implementation, the work of the helper
>  is somewhat expensive and should only be performed once. An
> alternate solution can be achieved by pushing the universal qualifier
> for the result type down into the handler:
> 
> type 'a handler = { handle : 'b . 'a -> (string -> 'a -> 'b, 'b) 
> writer }
I think it's reasonable to use universal qualifier here.

> I am forced into reworking the helper parameter function, wf, to also
>  become a record in order for it to be universally qualified:
> 
> type 'a field_handler = { write_field : 'b . string -> 'a -> (unit ->
>  string -> 'a -> 'b) -> 'b }
> 
> This works:
> 
> let helper name wf = { handle = fun a k -> wf.write_field name a k }
>  let f = helper "f" write_int_field

It's hard to tell where a better option is without knowing your overall
design on types and data structures. On the other hand, I would usually
restrict universal qualifiers into a range as small as possible. In your
example, I would probably define as the follows:

<code>
type 'a handler = { handle: 'a -> (string * 'a) writer }
and  'a writer = { write: 'b. (unit -> 'a -> 'b) -> 'b }

let helper name wf = { handle = wf name }
let write_int_field s i = { write = fun k -> k () (s, i+1) }
let f = helper "f" write_int_field
</code>

which seems simpler to me. However this really depends on your overall
design.

HTH.

--
Zheng