2011-12-05 12 views
15

Jednym z problemów z transformatorami monady, które znajduję, jest potrzeba wykonania operacji w prawej monadzie. Pojedyncza lift tu i tam nie jest złe, ale czasami są funkcje, które wygląda następująco:Praca na permutowanym stosie transformatora monadowego

fun = do 
    lift a 
    lift b 
    c 
    lift d 
    lift e 
    f 

Chciałbym móc napisać tę funkcję w następujący sposób:

fun = monadInvert $ do 
    a 
    b 
    lift c 
    d 
    e 
    lift f 

To o połowę numer lift s i sprawia, że ​​kod jest czystszy.

Pytanie brzmi: w przypadku jakich monad jest możliwa monadInvert? Jak utworzyć tę funkcję?

Dodatkowe punkty: zdefiniuj dla monad m, która jest instancją MonadIO.

Tytuł tego pytania mówi o permutacjach: w rzeczy samej, jak radzić sobie z dowolnymi permutacjami stosu monad transformatora?

+0

Bardzo wątpię, że możesz (ale być może uda ci się użyć jakiegoś złego oszustwa). Myślenie o typach po prostu mi nie pasuje. –

+0

Naprawdę nie jest to rozwiązanie gotowe do łopaty, ale możesz przeczytać [ten artykuł] (http://www.cs.umd.edu/~mwh/papers/monadic.pdf) warty przeczytania; od abstrakcji: "nasz algorytm wstawia niezbędne wiązania, jednostki i morfizmy monad do monady, tak aby typ programu sprawdzał" – acfoltzer

Odpowiedz

10

Możesz być zainteresowany Monads, Zippers and Views, Virtualizing the Monad Stack przez Tom Schrijvers i Bruno Oliveira.

Nie odnosi się to do twojego punktu widzenia dotyczącego redukcji wind, ale jest to interesujące podejście do problemu "permutacji monad".

Oto streszczenie:

Praca ta ma na celu monadycznego komponentów wielokrotnego użytku i bardziej wytrzymałe zmian przez zastosowanie dwóch nowych technik wirtualizacji monady stosu: zamek monady i monada widoki. Monadowy zamek błyskawiczny jest monadą transformatora, który tworzy wirtualne monadowe stosy przez zignorowanie poszczególnych warstw w betonowym stosie. Widoki Monad zapewniają ogólną architekturę dla wirtualizacji stosu monad: dodatkowo jednoczęściowy zamek błyskawiczny i integrację z szeroką gamą innych wirtualizacji. Na przykład, poszczególne widoki umożliwiają ograniczony dostęp do monad ze stosu w postaci . Co więcej, widoki monad mogą być używane przez komponenty do , zapewniając mechanizm podobny do wywołania, aby uzyskać dostęp do poszczególnych warstw monadowego stosu. Dzięki tym dwóm mechanizmom wymagania komponentów w postaci monadowego kształtu nie muszą już być dosłownie odzwierciedlone w betonowym stosie monad, czyniąc te komponenty bardziej powtarzalnymi i odpornymi na zmiany.

16

Po pierwsze, tak naprawdę nie potrzebujesz tak dużego podnoszenia. Dla transformatorów monada następujące tożsamości przytrzymanie:

lift c >>= lift . f = lift (c >>= f) 
lift c1 >> lift c2 = lift (c1 >> c2) 

To nie jest rzadkością, aby napisać:

x <- lift $ do 
    {- ... -} 

Dalej jest: Podczas korzystania z biblioteki jak MTL lub monadLib (tjbiblioteki oparte klasy typu zamiast transformatory bezpośrednio), to faktycznie można dotrzeć do najbardziej monads leżących bezpośrednio:

c :: StateT MyState (ReaderT MyConfig SomeOtherMonad) Result 
c = do 
    x <- ask 
    y <- get 
    {- ... -} 

Wreszcie, jeśli naprawdę potrzebują dużo podnoszenia mimo tych dwóch punktów, należy rozważyć napisanie własnego monady lub nawet użyć zupełnie innej abstrakcji. Używam strzałki automatu do obliczeń stanowych zamiast monady stanowej.

+1

To nie jest rozwiązanie, ale dzięki. Zauważ, że nie mogę napisać 'lift (a >> b >> c)', ponieważ a, b, c są z dwóch różnych monad. – Tener

1

Jestem przede wszystkim pewność, że to, czego decribing jest niemożliwe do IO, który zawsze jest najgłębsza monada:

Martin Grabmüller: Monad Transformatory krok po kroku, dostępne w http://www.grabmueller.de/martin/www/pub/

Downa w tym dokumencie nazywamy liftIO w eval6, aby wykonywać operacje wejścia/wyjścia. Dlaczego musimy podnieść w tym przypadku? Ponieważ nie istnieje klasa IO dla , którą możemy utworzyć jako typ. W związku z tym, w przypadku działań we/wy, mamy zadzwonić windy do wysyłania poleceń do wewnątrz

Generalnie dla monad mniej restrykcyjnych niż IO (takie jak błąd i państwo) kolejność nadal sprawach dla semantyki, więc nie można zmienić kolejności stosu tylko po to, by uczynić składnię wygodniejszą.

Dla niektórych monad, takich jak Czytelnik, które są centralne (w tym, że dojeżdżają do stosu), Twój pomysł nie jest wyraźnie niemożliwy. Nie wiem, jak to napisać. Przypuszczam, że byłaby to klasa typu CentralMonad, która to jest ReaderT, z pewną implementacją ...

Powiązane problemy