Sent from my iPad

On Nov 15, 2011, at 7:18 PM, wren ng thornton <w...@freegeek.org> wrote:

> On 11/15/11 12:33 PM, Yitzchak Gale wrote:
>> Simon Peyton-Jones wrote:
>>>>>> Trouble is, what type does this have?
>>>>>>   f x = x {}
>> 
>> Malcolm Wallace wrote:
>>>>> f :: a ->  a
>> 
>> Ian Lynagh wrote:
>>>> That wouldn't help the original poster, as it is incompatible with
>>>> f :: Foo Clean ->  Foo Dirty
>> 
>> Only because in that expression the type of x is not known.
>> 
>>>>>> ...the whole feature of type-changing update is (as you know)
>>>>>> a bit obscure and not widely used, so it'd be adding
>>>>>> complexity to an already-dark corner.
>> 
>> To me, at least, that is surprising. The report implies that
>> record updates are just sugar for the given case expression.
>> Whether or not it changes a type parameter seems
>> unimportant.
>> 
>> In fact, I would even advocate adding a line of explanation
>> in the Report that this is a convenient way of copying
>> a value from an ADT to itself with a different type
>> as its parameter. I agree with Malcolm that this is
>> analogous to using empty record syntax in a pattern
>> to avoid hard-coding the number of parameter to
>> a constructor.
>> 
>> I usually avoid using the combination of type parameters and
>> record syntax altogether, mainly because this obvious syntax
>> doesn't work. Perhaps that's the reason why type-changing
>> update is not widely used.
>> 
>> (Admittedly, I didn't think of Herbert's trick. But doesn't
>> that seem like somewhat of an ugly hack?)
>> 
>> Are you hesitant because of implementation difficulty,
>> or only because you are worried about the semantics
>> being confusing? In my opinion, it's more confusing
>> the way it is now.
> 
> For what it's worth, I do the exact same thing in the project I've been 
> working on. The phantom type is a clean/dirty bit even :)
> 
> It's an incredibly helpful thing to have for records. Especially for the 
> context I'm in: I'm generating summary data over gobs of input, but the input 
> can come incrementally. So long as the core of the summary is correct, then I 
> don't care about maintaining the cache fields while I'm just shoveling data 
> in; but I do want to make sure the caches are valid before I try to get any 
> information out. This is exactly the sort of type-level hackery which makes 
> Haskell a joy to work in and other languages such a pain.
> 
> So far I've just defined helper functions to adjust the phantom type[1], each 
> of which is implemented by (\x -> x { foo = foo x }). It's a horrible hack, 
> but at least it's hidden away in library functions instead of something I 
> have to look at. The annoying part is that when I adjust the members of the 
> records, if I remove or rename foo then I have to fix all those coercion 
> functions too.
> 


My biggest issue is loss of sharing, but you could always use

castFoo = asTypeOf unsafeCoerce $ \x -> x { foo = foo x }

to maximize sharing, but that doesn't help with the code rewriting,

Or less horrifically just carry the phantom in a newtype wrapper wrapped around 
your record, and cast by putting it on and taking it off, which also maximizes 
sharing in exchange for newtype noise on access.


_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to