2011-12-30 3 views
23

Dire che ho un po 'di foo :: Maybe Int e voglio legarlo per esempio con bar :: Int -> MaybeT (Writer String) Int, quale sarebbe il modo idiomatico per farlo?Come iniettare un valore Forse in MaybeT

potrei definire la mia propria funzione liftMaybe, e quindi utilizzare tale, come:

let liftMaybe = maybe (fail "Nothing") return in liftMaybe foo >>= bar 

Ma c'è un (o almeno conciso) modo più idiomatico per farlo?

risposta

20
MaybeT . return :: (Monad m) => Maybe a -> MaybeT m a 

Penso che sia un peccato che non abbia un nome standard. Una forma più generale è

liftMaybe :: (MonadPlus m) => Maybe a -> m a 
liftMaybe = maybe mzero return 

che è preferibile l'uso di fail. Lo metterei semplicemente in un modulo conveniente da qualche parte.

Hayoo mostra un wide variety of names per questa funzione; di quelli, maybeZero è il mio preferito. liftMaybe, per quanto ovvio, non appare.

+0

Thx, questo è già un miglioramento. Ma possiamo fare ancora meglio? – user1078763

+0

Rispetto a 'forse mzero return'? Ne dubito; è già molto breve Non suggerisco di elencarlo ovunque lo usi; metterlo in un modulo comune è un'idea molto migliore. – ehird

+0

Questo può anche essere visto come un uso specifico di qualcosa come 'fmapT :: (Monad m, Monad n, MonadTransformer t) => (forall a. Ma -> na) -> (forall a. Tma -> tna)' , ma solo se fingiamo che 'Maybe' sia in realtà' MaybeT Identity'. Non credo che la funzione sia possibile in tutta la generalità, ma potrebbe essere trasformata in una classe di tipo con specifici trasformatori di monade come istanze. –