What are good Haskell conventions for managing deeply nested bracket patterns? -
I am currently working in an HDF 5C library with Haskell binding. Like many libraries, it uses several points in the call of its functions.
Use the Haskell function, such as alloca
, android
, etc. to allocate and release common resources "best practice" I often enter many nested brackets. For example, here is a small fraction for the HDF 5 binding:
Select the hyperslab RID DN name = Dataset with RID dName $ \ dID -> What to do & lt; - Dataspace 10 $ \ dstDS - & gt; Do srcDS & lt; - c'H5Dget_space did dat & lt; - alloca3 (0, 1, 10) $ \ (start, sort, count) - & gt; Make a mistake & lt; - c'H5Sselect_hyperslab srcDS c'H5S_SELECT_SET start string count nullPtr - do some work ... return value alloca3 (a, b, c) verb = alloca $ \ aP - & gt; AP to Eloca $ $ bP - & gt; BPB light $$ cp - & gt; In the above code, nested brackets are bracket functions which I have written with dataset
, withDataspace
/ Code>, and alloca3
, which I wrote to prevent bracket nesting from going deep into the other 3 levels in the code. For C libraries with C acquisition calls and pointer arguments, coding with standard bracket primitive can be unbearable (this is why I wrote alloca3
to reduce nesting.)
Normally, would any of the best practices or coding techniques be used to allocate resources to help reduce the nesting of brackets and various resources (such as C-calls) The Ykta? I have found that the only option is a transformer, which is seen from the tutorial that it has been created to make / make interling resources possible, and not to simplify the bracket pattern.
I was recently. Recurring pattern (a -> IO r) - & gt; IO r
, where a given function is executed within some resource allocation context, this value is given the value of a
. And it's just that, which is easily available in Haskel, we can write:
Import control. Import import control Monad Import import control Silence Io Class Import Control Exception (bracket) import overseas PCT Import Foreign Scable (Storyer) Import Foreign Martial Alok (Aloka) Elocassy :: Slayer A => Conti r IO (Ptr a) allocaC = ContT alloca bracket C :: IO a - & gt; (A -> Io B) - & gt; Country RIO Start a Bracket C End = Content (Bracket Start & End) Bracket C_ :: IOA - & gt; IoB - & gt; Content Rio A Bracket C- Start End = Content (Bracket Start (Constant End) - ... etc ... - | Example: Main :: IO (Main) = Flip RunContent Returns $ Bracket C_ (putStrLn "start1") (putStrLn "end1") bracket C_ (putStrLn "start2") (putStrLn "end2") liftIO $ putStrLn "... "/ Code> The standard maud / applicant functions allow you to simplify a lot of code, for example:
allocAndPoke :: (Storable a) = & Gt; A - & gt; Country RIO (PTR A) Alok Endpok X = Alocaic & gt; & Gt; = \ Ptr - & gt; LIFEIO (Peak PTR X) & gt; & Gt; Return PTR - Mons Alloca3 will probably not require an example, just as an example: alloca3C (a, b, c) = (,) & lt; $ & Gt; AllocAndPoke is a & lt; * & Gt; AllocAndPoke b & lt; * & Gt; AllocAndPoke C AllocaManyC :: (Storable A) = & gt; [A] - & gt; ContT r IO [Ptr a] allocaManyC = mapM alloc endocoke
Comments
Post a Comment