[GHC] #10744: Allow oneShot to work with unboxed types
GHC
ghc-devs at haskell.org
Thu Aug 6 15:42:26 UTC 2015
#10744: Allow oneShot to work with unboxed types
-------------------------------------+-------------------------------------
Reporter: akio | Owner:
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by akio):
I use it in the fast-builder package [1], which aims to be a ByteString
builder implementation that is significantly faster than the standard one.
The main Builder type looks like this
{{{#!hs
type Builder = DataSink -> State -> State
data DataSink = -- abstract
data State = -- abstract
-- | Builder concatenation.
(<>) :: Builder -> Builder -> Builder
a <> b = \sink s = b sink (a sink s)
-- | Primitive builder.
int :: Int -> Builder
int = -- implementation omitted.
}}}
As an example, the user may write code like this to serialize a list of
Ints:
{{{#!hs
serialize :: [Int] -> Builder
serialize list = int (length list) <> foldr (<>) mempty (map int list)
}}}
For `serialize` to work efficiently, I really want it to have the arity of
3. However, simply inlining `int` and `(<>)` only gives
{{{#!hs
serialize = \list -> let len = length list in \sink s -> ...
}}}
So it gets arity 1, which means it has to allocate a lambda and then call
it.
By default GHC doesn't eta-expand `serialize` because it wants to avoid
evaluating `length` multiple times. However, I want GHC to produce better
code in the assumption that the resulting Builder will be used at most
once, because using the same Builder multiple times is usually a bad idea
anyway (you should instead turn it into a ByteString and use that
ByteString multiple times). I express this preference by inserting calls
to `oneShot` into the definitions of `(<>)`, `int`, etc.
The current type of `oneShot` means `State` has to be a lifted type.
Ideally I'd like to use something like `(# Addr#, Addr#, State# RealWorld
#)`.
[1]: http://hackage.haskell.org/package/fast-builder
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10744#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list