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.


[1] set bit to Clean, set bit to Dirty, and unsafe set bit to 'a'.

--
Live well,
~wren

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

Reply via email to