
Hi
what is general purpose stuff. I don't think there is anything wrong with magic for primitive types, but if there is a useful general-purpose mechanism trying to get out, let's liberate it.
I think the tension comes from representing String's as CString's, not actual lists of Char and (:). If the simple representation was used, then things like case on a known constructor would deal with a lot of these cases. However, for String, its probably too expensive in terms of compile time and compile memory to keep the unpacked representation.
But I'd like a clear spec first.
PROPOSAL 1: Add the following rules to the simplifier:
case unpackCString# "" of ==> case [] of case unpackCString# "xyz" of ==> case (C# 'x': unpackCString# "yz") of
Pros: Doesn't introduce any new API or other long-term maintenance issues. A necessity for certain optimisations. Cons: Makes the simplifier slightly more complex - but I hope not by much! PROPOSAL 2: Add some primitives and hard-coded simplifications: (I'm giving an example with length#, but I imagine head#, tail#, null# and some others would also be handy) Add the following in GHC.<somewhere> length# :: CString -> Int {-# RULE "length/string" forall xs . length (unpackCString xs) = length# xs #-} Add the rules to the simplifier: length# "string" = <the result> Pros: length "haskell" becomes a compile-time constant. Very useful for the ByteString people. Makes RULES and CString interact better, with better optimisation possibilities. Cons: Requires defining a small API and maintaining it. Requires more work to the simplifier, but still should be fairly self-contained. Cries out for a generalisation (but I don't think there is a good one). SUMMARY: I think Proposal 1 is a really good idea, with a little effort and a lot of return. I think Proposal 2 is more effort than proposal 1, with probably less return - but may still be worth it. I think Don will really want Proposal 2. Thanks Neil