2011-06-27 19 views
7

मैं Hoopl लाइब्रेरी का उपयोग कर रहा हूं और फिर से लिखने के दौरान कुछ राज्य ले जाना चाहता हूं। पुनर्लेखन कार्य मोनैड के इस्तेमाल के बारे में पॉलिमॉर्फिक हैं, लेकिन मैं यह नहीं समझ सकता कि लाइब्रेरी के Fuel मोनैड में से एक के साथ State मोनैड को कैसे जोड़ा जाए।मैं होउप्ल में एक राज्य मोनड के साथ चेकिंगफ्यूलमोनाड को कैसे जोड़ सकता हूं?

नीचे एक न्यूनतम उदाहरण है। MyMonad एक समानार्थी है जो होप्ल के CheckingFuelMonad और State मोनैड को ध्वज लेते हुए समानार्थी है। Stmt मेरी मध्यवर्ती भाषा के लिए सिर्फ प्लेसहोल्डर है और वास्तव में महत्वपूर्ण नहीं है।

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

लेकिन इस संकलन नहीं होगा - GHC शिकायत rewrite गलत प्रकार है:

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))) 

मैं क्या संभव करना चाहता हूँ है? मैं rewrite फ़ंक्शन को सही तरीके से कैसे लिख सकता हूं?

+0

मैं सुपर अविश्वसनीय हूं कि यह पुनर्लेख ध्वनि है। यह बहुत डोडी व्यवसाय है। –

उत्तर

4

हुप्पल कोड के माध्यम से एक ब्राउज़ से पता चलता है कि चेकिंगफ्यूलमोनाड मोनाडट्रान का उदाहरण नहीं है, और आप इसे एक नहीं बना सकते हैं, क्योंकि इसके निर्माता निर्यात नहीं किए जाते हैं। आप तथापि कर सकते हैं CheckingFuelMonad के चारों ओर एक StateT लपेट, इसलिए जैसे:

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

मजाकिया हिस्सा है, यदि आप 'चेकिंगफ्यूलमोनाड' के कार्यान्वयन को देखते हैं, तो यह केवल 'स्टेटटी ईंधन' है। –

+0

इससे मुझे थोड़ा आगे निकलने में मदद मिलती है! दुर्भाग्य से 'माईमोनाड' 'फ्यूलमोनाड' का एक उदाहरण होना चाहिए, और मुझे नहीं लगता कि मैं इसे एक बना सकता हूं क्योंकि कक्षा के सदस्यों को निर्यात नहीं किया जाता है। हालांकि, मैं 'mkBRewrite (\ s f -> evalStateT (rewriter s f) गलत से दूर जाने में सक्षम हूं) '। दुर्भाग्य से मुझे लगता है कि इसका मतलब है कि राज्य व्यक्तिगत बयानों में संरक्षित नहीं होगा - हम देखेंगे! –

+0

@ जस्टिन बेली: 'फ्यूलमोनाड' से सबकुछ ऐसा लगता है कि यह मुझे निर्यात किया गया है। साथ ही, मुझे पूरा यकीन है कि ऑर्डर * आसन्न * 'स्टेटटी' परतों के लिए अप्रासंगिक है, इसलिए' एससीएलवी का संस्करण 'SimpleFuelMonad' के अंदर 'राज्य' डालने के बराबर होना चाहिए। –

1

खैर, अपने वर्तमान त्रुटि के तत्काल कारण सरल है। अंतिम अभिव्यक्ति क्या है यदि f सत्य है? अगर हम इस ले:

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 

... और सब कुछ लेकिन True शाखा को दूर हम पाते हैं:

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

... जो करने के लिए सरल:

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

के प्रकार क्या है return $ return $ Just emptyGraph?

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

दूसरे शब्दों में, आपके पास अतिरिक्त return है। (Monad m) => CheckingFuelMonad m स्वयं Monad है, भले ही CheckingFuelMonad को एक मोनड ट्रांसफॉर्मर के रूप में परिभाषित नहीं किया गया है, इसलिए आपको केवल एक मोनैड परत return पर मिली है।

+0

किसी अन्य प्रकार की त्रुटि में परिणाम लौटने से रोकना ... :( –

+0

@ जस्टिन बेली: इसलिए मैंने "तत्काल कारण" क्यों कहा। 'डू 'ब्लॉक के बाहर' वापसी 'को हटाकर इसे वास्तविक समस्या में कम कर देता है, जो कि क्या 'एससीएलवी' के बारे में बात करते हैं। –