2012-02-03 15 views
11

Mientras miraba a través del paquete de transformadores, encontré este transformador de mónada llamado IdentityT.¿Cuál es el propósito del transformador IdentityT?

Aunque entiendo cómo se utiliza la mónada de identidad (por ejemplo State es sólo un alias para StateT Identity) y cómo mónada transformadores de trabajo en general, no tengo idea de cómo se relaciona con IdentityT.

Dado que no está en el MTL, supongo que se agregó allí para completarlo y no tiene ningún uso práctico. ¿Es eso correcto?

Respuesta

6

bien esta documentación a la que hace decir

Esto es útil para las funciones parametrizadas por un transformador mónada.

Aunque no conozco ninguna situación en la que este sea realmente el caso. Teóricamente, si tiene una función como foo :: (MonadTrans t, Monad m) => t m a -> b para algún b útil, entonces puede querer "atontarlo" esencialmente a m a -> b usando t = IdentityT.

Pero IdentityT es MonadTrans es Identity es Monad. Es el transformador de "paso a través", ya que Identity es la mónada de "paso a través". Solo mira la fuente; es bastante simple. IdentityT SomeMonad a debe comportarse de manera idéntica a SomeMonad a, la única diferencia es la presencia de un tipo nuevo (que, por supuesto, se elimina en el momento de la compilación)

2

Hay un uso que aquí se propone (presumiblemente el origen de IdentityT: http://www.haskell.org/pipermail/libraries/2007-June/007563.html

El uso principal parece ser la de permitir la flexibilidad a nivel de código fuente, por ejemplo, alguien puede editar el código fuente a xmonad y sustituir su propio UserT sin editar demasiado código.

Traté de ver cómo eso podría funcionar para una biblioteca, puede usarlo para proporcionar un marcador de posición para insertar una mónada en el medio de una pila, no estoy seguro de una gran carcasa para eso sin embargo. Aquí está mi ejemplo ideado:

{-# 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] 
Cuestiones relacionadas