2011-06-27 11 views
7

używam biblioteki Hoopl i chciałby mieć przy sobie stan się podczas przepisywania. Funkcje przepisujące są polimorficzne dotyczące monady używane, ale nie mogę dowiedzieć się, jak połączyć State monady z jednym z biblioteki Fuel monad.Jak mogę połączyć CheckingFuelMonad z Monadą Stanową w Hoopl?

Poniżej jest przykład minimalny. MyMonad jest synonimem łączącym monadę Hoopla z CheckingFuelMonad i State niosącą flagę. Stmt jest tylko symbolem zastępczym dla mojego języka pośredniego i nie jest tak naprawdę ważny.

{-# LANGUAGE GADTs, RankNTypes #-} 

import Compiler.Hoopl 
import Control.Monad.State 

type MyMonad = CheckingFuelMonad (State Bool) 

data Stmt e x where 
    Bind ::() -> Stmt O O 

rewriter :: forall e x. Stmt e x -> Fact x() -> MyMonad (Maybe (Graph Stmt e x)) 
rewriter (Bind())() = return $ do 
    f <- get 
    if f 
    then return $ Just emptyGraph 
    else return Nothing 

Ale nie będzie to skompilować - GHC zarzuca rewrite ma niewłaściwy typ:

Couldn't match expected type `Graph' Block Stmt e x' 
     against inferred type `Maybe (g n O O)' 
    Expected type: CheckingFuelMonad 
        (State Bool) (Maybe (Graph Stmt e x)) 
    Inferred type: CheckingFuelMonad 
        (State Bool) (Maybe (Maybe (g n O O))) 

jest to, co chcę zrobić, to możliwe? Jak poprawnie napisać funkcję rewrite?

+0

jestem bardzo przekonany, że ten tekst poprawiony jest dźwięk. To bardzo ryzykowny biznes. –

Odpowiedz

4

Przejrzyj kod hoopl ujawnia, że ​​CheckingFuelMonad nie jest instancją MonadTrans i nie może to jedno, ponieważ jego konstruktorzy nie są eksportowane. Ci może jednak zawinąć StateT wokół CheckingFuelMonad, tak:

{-# LANGUAGE GADTs, RankNTypes #-} 

import Compiler.Hoopl 
import Control.Monad.State 

type MyMonad = StateT Bool SimpleFuelMonad 

data Stmt e x where 
    Bind ::() -> Stmt O O 

rewriter :: forall e x. Stmt e x -> Fact x() -> MyMonad (Maybe (Graph Stmt e x)) 
rewriter (Bind())() = do 
    f <- get 
    if f 
    then return $ Just emptyGraph 
    else return Nothing 
+0

Zabawną częścią jest, jeśli spojrzysz na implementację 'CheckingFuelMonad', to po prostu' StateT Fuel'. –

+0

To pomaga mi trochę dalej! Niestety 'MyMonad' musi być instancją' FuelMonad' i nie sądzę, żebym mógł to zrobić, ponieważ członkowie klasy nie są eksportowani. Jednak jestem w stanie uciec 'mkBRewrite (\ s f -> evalStateT (rewriter s f) False)'. Niestety myślę, że oznacza to, że państwo nie będzie zachowane w poszczególnych wypowiedziach - zobaczymy! –

+0

@Justin Bailey: Wszystko z 'FuelMonad' wygląda na wyeksportowane do mnie. Poza tym jestem przekonany, że kolejność * nie ma znaczenia dla * sąsiednich * warstw 'StateT', więc wersja' sclv' powinna być równoważna umieszczeniu 'State' w' SimpleFuelMonad'. –

1

dobrze, bezpośrednią przyczyną obecnego błędu jest prosta. Jakie jest końcowe wyrażenie, jeśli f jest prawdziwe? Jeżeli weźmiemy pod uwagę to:

rewriter :: forall e x. Stmt e x -> Fact x() -> MyMonad (Maybe (Graph Stmt e x)) 
rewriter (Bind())() = return $ do 
    f <- get 
    if f 
    then return $ Just emptyGraph 
    else return Nothing 

... i usuń wszystko oprócz True oddziału otrzymujemy:

rewriter :: forall e x. Stmt e x -> Fact x() -> MyMonad (Maybe (Graph Stmt e x)) 
rewriter (Bind())() = return $ do 
    return $ Just emptyGraph 

... co upraszcza się do:

rewriter :: forall e x. Stmt e x -> Fact x() -> MyMonad (Maybe (Graph Stmt e x)) 
rewriter (Bind())() = return $ return $ Just emptyGraph 

Jaki jest typ return $ return $ Just emptyGraph?

(Monad m1, Monad m2, GraphRep g) => m1 (m2 (Maybe (g n O O))) 

Innymi słowy, masz tam dodatkowy return. (Monad m) => CheckingFuelMonad m sama jest Monad, choć CheckingFuelMonad nie wydaje się być zdefiniowana jako transformator monady, więc masz tylko jedną warstwę monady do return z.

+0

Zdejmowanie zwrotu skutkuje błędem innego typu ... :( –

+0

@Justin Bailey: Dlatego właśnie powiedziałem "bezpośrednią przyczynę". Usunięcie 'return' poza blokiem' do' powoduje jedynie zmniejszenie do rzeczywistego problemu, który jest o czym mówi 'sclv'. –

Powiązane problemy