2012-03-15 13 views
8

Spesso mi ritrovo a voler inserire funzioni regolari in una sequenza "bindata". Come in questo esempio inventato:Legatura sequenziale con funzioni pure

getLine >>= lift (map toUpper) >>= putStrLn 

ho bisogno di definire la funzione di sollevamento lift :: (a -> b) -> a -> m b per fare questo lavoro. Il problema è che non so di una tale funzione, e non sembra neanche lo Hoogle. Trovo strano questo dato che per me è assolutamente sensato.

Ora, ci sono probabilmente altri modi per farlo funzionare, ma mi piace il modo in cui il codice di stile point-free mi consente di scansionare la linea in un passaggio per capire cosa sta succedendo.

La mia domanda si riduce a questo: mi manca qualcosa o come mai non c'è una funzione come ascensore. La mia esperienza in Haskell è ancora molto limitata, quindi presumo che la maggior parte delle persone risolva questo problema in un modo diverso. Qualcuno può spiegarmi il modo idiomatico di risolvere questo.

risposta

18

Ci sono tre modi idiomatiche.

  1. Non utilizzare legatura; utilizzare il primo colpo sulla vostra ricerca Hoogle invece:

    liftM (map toUpper) getLine >>= putStrLn 
    

    Ci sono una varietà di alternative di ortografia liftM, come fmap o (<$>).

  2. Inline la funzione lift si definisce:

    getLine >>= return . map toUpper >>= putStrLn 
    
  3. usare le leggi monade di fondere le ultime due si lega in Opzione 2:

    getLine >>= putStrLn . map toUpper 
    
+1

vorrei mettere 'foo >> = ritorno. bar >> = baz' ultimo nella lista. Va bene con catene più lunghe, ma nei casi brevi come nell'esempio, 'foo >> = baz. bar' è molto più leggibile IMO. –

+0

In realtà penso 'pippo >> = ritorno. bar >> = baz' è un modo pulito. Non mi è venuto in mente che quella in realtà è la funzione di sollevamento che stavo cercando. –

+4

'putStrLn. map toUpper = << getLine' sembra abbastanza carino. Mi piace usare '= <<' poiché assomiglia all'applicazione della funzione. – danr

3

utilizzare l'istanza Functor in questi casi:

> import Data.Char 
> import Data.Functor 
> map toUpper <$> getLine >>= putStrLn 
foo 
FOO 
>