Haskell trickery

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Haskell trickery

Joel Reymont
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?

Last but not least, what is

      case action addr    of { IO action ->
      case action s       of { (# s, r #) ->


        Thanks, Joel

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Haskell trickery

Donald Bruce Stewart
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
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe