Attualmente sto lavorando con i collegamenti Haskell a una libreria C HDF5. Come molte librerie C, questa utilizza molte indicazioni nelle sue chiamate di funzioni.Quali sono le convenzioni Haskell per la gestione di schemi di parentesi profondamente annidati?
I normali funzioni di "best practice" Haskell per ripartizione e liberando risorse c Seguire le bracket pattern, come alloca
, withArray
, ecc li utilizzano, spesso immettere diverse parentesi nidificate. Per esempio, ecco un piccolo estratto per gli attacchi HDF5:
selectHyperslab rID dName = withDataset rID dName $ \dID -> do
v <- withDataspace 10 $ \dstDS -> do
srcDS <- c'H5Dget_space dID
dat <- alloca3 (0, 1, 10) $ \(start, stride, count) -> do
err <- c'H5Sselect_hyperslab srcDS c'H5S_SELECT_SET start stride count nullPtr
-- do some work ...
return value
alloca3 (a, b, c) action =
alloca $ \aP -> do
poke aP a
alloca $ \bP -> do
poke bP b
alloca $ \cP -> do
poke cP c
action (aP, bP, cP)
Nel codice di cui sopra, le parentesi annidate sono funzioni staffa ho scritto withDataset
, withDataspace
, e alloca3
, che ho scritto per evitare che la staffa di nidificazione di andare un altro 3 livelli in profondità nel codice. Per le librerie C con un sacco di chiamate di acquisizione delle risorse e gli argomenti di puntatore, codifica con le primitive di supporto standard in grado di ottenere ingestibile (che è il motivo per cui ho scritto alloca3
per ridurre la nidificazione.)
Quindi in generale, ci sono delle migliori pratiche o tecniche di codifica per aiutare a ridurre l'annidamento di parentesi quando è necessario allocare e deallocare molte risorse (come con le chiamate C)? L'unica alternativa che ho trovato è il trasformatore ResourceT, che dal tutorial sembra essere progettato per rendere possibile l'acquisizione/rilascio di risorse di interlacciamento e non per semplificare il modello di parentesi.
Non sembra come tutte le allocazioni dipendono l'uno dall'altro, quindi scrivi prima tutti gli allocati, con lo stesso livello di indentazione, quindi il resto della tua funzione. A seconda della lunghezza, potresti anche scriverli sulla stessa riga: 'alloca $ \ a -> alloca $ \ b -> alloca $ \ c -> fai \ n ...' – user2407038
La discussione su https: // www .reddit.com/r/haskell/commenti/s49kk/using_contt_to_please_the_eye/parla molto di idiomi per questo. – Carl
Questo sembra anche un altro livello di monade attorno all ''alloca'. –