[Haskell-cafe] Haskell trickery

Donald Bruce Stewart dons at cse.unsw.edu.au
Tue Dec 20 05:24:49 EST 2005


joelr1:
> Folks,
> 
> How is one to interpret the following? I'm particularly interested in  
> the "IO $ \ s -> " notatoin as I have never seen that before.
> 
> allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
> allocaBytes (I# size) action = IO $ \ s ->
>      case newPinnedByteArray# size s      of { (# s, mbarr# #) ->
>      case unsafeFreezeByteArray# mbarr# s of { (# s, barr#  #) ->
>      let addr = Ptr (byteArrayContents# barr#) in
>      case action addr    of { IO action ->
>      case action s       of { (# s, r #) ->
>      case touch# barr# s of { s ->
>      (# s, r #)
>   }}}}}
> 
> Lemmih suggested that this is unrolling the code (manual inlining?)  
> but how much speedup is that buying you?

Doesn't this style come from the fact that unboxed primops are being
called, which require explicit state args to be threaded (the multiple,
shadowed 's' results in the unboxed tuples)?

If we check the type of the various primops:
    newPinnedByteArray# :: Int# -> State# s -> (# State# s, MutByteArr# s #)
    unsafeFreezeByteArray# :: MutByteArr# s -> State# s -> (# State# s, ByteArr# #)
and so on , we see that they're all set up to have a state token
threaded explicitly, so the sequencing works.

So the type forces you to step inside the IO container. The primops are
used for efficiency (and this is low level code anyway), but stepping
inside IO is just so the typing works. All the primops then get boxed up
into a nice little IO action.

The only place I've ever seen this style are when threading state to
primop calls.

-- Don


More information about the Haskell-Cafe mailing list