Какова цель трансформатора IdentityT? - PullRequest
12 голосов
/ 03 февраля 2012

Просматривая пакет трансформаторов, я обнаружил этот монадный трансформатор IdentityT .

Хотя я понимаю, как используется монада Identity (например, State - это просто псевдоним StateT Identity) и как вообще работают монадные преобразователи, я понятия не имею, как это относится к IdentityT.

Так как его нет в MTL, я думаю, он был добавлен туда только для полноты и не имеет практического применения. Это правильно?

Ответы [ 2 ]

6 голосов
/ 03 февраля 2012

Хорошо, связанная документация говорит

Это полезно для функций, параметризованных монадным преобразователем.

Хотя я не знаю ни о каких ситуациях, когда это действительно так. Теоретически, если у вас есть такая функция, как foo :: (MonadTrans t, Monad m) => t m a -> b для некоторого полезного b, то вы можете захотеть "потушить" ее по существу до m a -> b, используя t = IdentityT.

Но IdentityT означает MonadTrans, что Identity означает Monad. Это «сквозной» трансформатор, так как Identity - это «сквозная» монада. Просто проверьте источник; это довольно просто. IdentityT SomeMonad a должен вести себя идентично SomeMonad a, единственное отличие заключается в наличии дополнительного нового типа (который, конечно, удаляется во время компиляции)

2 голосов
/ 03 февраля 2012

Здесь предлагается использование (предположительно, происхождение IdentityT: http://www.haskell.org/pipermail/libraries/2007-June/007563.html

Основное использование, по-видимому, заключается в том, чтобы обеспечить гибкость на уровне исходного кода, например, кто-то может отредактировать исходный код в xmonad и заменить егособственный UserT без редактирования слишком большого количества кода.

Я попытался увидеть, как это может работать для библиотеки - вы можете использовать ее для предоставления заполнителя для вставки монады в середину стека, я не уверенхотя это хороший пример. Вот мой надуманный пример:

{-# 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]
...