2012-02-03 17 views
11

Mentre osservavo il pacchetto dei trasformatori, ho trovato questo trasformatore monad chiamato IdentityT.Qual è lo scopo del trasformatore IdentityT?

Pur comprendendo come viene utilizzato monade Identity (ad esempio State è solo un alias per StateT Identity) e come monad trasformatori lavorare in generale, ho idea come che si riferisce a IdentityT.

Poiché non è nell'MTL, suppongo che sia stato aggiunto lì solo per completezza e non ha alcun uso pratico. È corretto?

risposta

6

Bene la documentazione collegata fa dire

Questo è utile per le funzioni parametrizzati da un trasformatore monade.

Anche se non sono a conoscenza di situazioni in cui questo è effettivamente il caso. In teoria, se hai una funzione come foo :: (MonadTrans t, Monad m) => t m a -> b per qualche utile b, allora potresti voler essere in grado di "ridimensionarlo" essenzialmente in m a -> b usando t = IdentityT.

Ma IdentityT è a MonadTrans quello che Identity è a Monad. È il trasformatore "pass-through", come Identity è la monade "pass-through". Basta controllare la fonte; è piuttosto semplice. IdentityT SomeMonad a dovrebbe comportarsi in modo identico a SomeMonad a, l'unica differenza è la presenza di un extra newtype (che, ovviamente, viene rimosso al momento della compilazione)

2

C'è una proposta di utilizzo qui (presumibilmente l'origine della IdentityT: http://www.haskell.org/pipermail/libraries/2007-June/007563.html

L'uso principale sembra essere quello di consentire la flessibilità a livello di codice sorgente, ad esempio, qualcuno può modificare il sorgente per xmonad e sostituire la propria UserT senza modificare troppo codice

Ho provato a vedere come potrebbe funzionare per una libreria: puoi usarla per fornire un segnaposto per l'inserimento di una monade nel mezzo di una pila, non sono sicuro di una buona idea per questo però. Ecco il mio esempio inventato:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

import Control.Monad.State 
import Control.Monad.List 
import Control.Monad.Reader 

type X m a = StateT Int (m IO) a 

something :: (Monad (m IO), MonadIO (m IO)) => (m IO) Int -> X m Int 
something a = do 
     x <- lift a 
     put (x + 1) 

     liftIO $ print x 
     return x 



listSomething = something $ ListT (mapM return [1,2,3,4]) 
plainSomething = return 5 :: IdentityT IO Int 

main = do 
    x <- runListT (execStateT listSomething 3) 
    print x 

    y <- runIdentityT (execStateT plainSomething 3) 
    print y 

runIdentity $ mapM (return . (+1)) [1..100]