2013-03-21 14 views
5

Buona giornata gente. Sto cercando alcuni chiarimenti sulle monadi per favore e usando bind (mentre si va in un composito .) per favore.Monade vincolanti in compositi (Haskell)

Così, per questo esempio:

--Monadic parts: 
readFile :: String -> IO File 
putStr :: String -> IO() 
-- Non monadic parts 
toMatrix :: String -> CustomMatrix 
toString :: CustomMatrix -> String 

In sostanza sto pigramente lettura di un file (readFile) poi produrre una matrice personalizzata, convertendo la matrice a un'uscita stringa. Quindi ritorno.

fileReading :: String -> IO 
fileReading file = putStr(toString . toMatrix . readFile file) 

Questo è quando ho iniziare a creare un pasticcio utilizzando legano >>= per andare da readFile file. C'è un modo per continuare a usare i compositi . e legare e comporre senza fare un pasticcio illeggibile (non proprio il mio obiettivo).

Come sempre, qualsiasi aiuto viene accolto con gratitudine. Grazie gente.

+2

I nomi di variabili e funzioni non possono iniziare con una cifra, quindi sto rinominando '2Matrix' e' 2String' nella domanda. – dave4420

+0

Scuse. Stavo riducendo i miei nomi di funzioni senza pensare. – BrownE

+1

L'analogia di '(.)' Per le funzioni di tipo 'a -> m b' per alcuni monad' m' è chiamata '(<= <)' (da 'Control.Monad') e si chiama Composizione di Kleisli. Puoi mescolarlo con '.' a seconda dei tipi di ciò che stai componendo. Per esempio. 'fileReading = putStr. accordare . toMatrix <= luqui

risposta

7

In questo esempio non è possibile scappare senza utilizzare della funzione monodica (come >>=). Non è possibile utilizzare la normale composizione di funzioni con i valori di I/O se si vuole effettivamente fare qualche IO.

Fortunatamente, si può ancora scrivere il codice piuttosto essere letti:

fileReading file = readFile file >>= putStr . toString . toMatrix 

Questo funziona perché i due . operazioni combinano due funzioni non-IO con una funzione di finale IO. A quel punto, hai due valori di I/O: una funzione IO String e una String -> IO() (l'intera espressione putStr . toString . toMatrix ha quel tipo). Questo è esattamente ciò che prende >>=, quindi tutto è pronto.

Se si desidera che il codice abbia lo stesso ordine di cui sopra, è possibile utilizzare l'operatore si legano a ritroso:

fileReading file = putStr . toString . toMatrix =<< readFile file 

Alcune persone trovano questa versione più leggibile perché tutto il codice "flussi" nella stessa direzione.