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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe