2013-05-06 7 views
7

मैं निम्नलिखित गया डेटा प्रकार:प्रतिमान मिलान

data Flow a = Continue a | Return Value 
newtype FlowT m a = FlowT {runFlowT :: m (Flow a)} 
type IStateM a = FlowT (StateT IState IO) a 

जहां IState कुछ रिकॉर्ड कुछ सूचियों आदि इकाई और MonadTrans FlowT के लिए उदाहरणों वाले के रूप में परिभाषित कर रहे हैं प्रकार है इस प्रकार है:

instance (Monad m) => Monad (FlowT m) where 
x >>= f = FlowT $ do 
        unwrapped <- runFlowT x 
        case unwrapped of 
         Continue v -> runFlowT (f v) 
         Return r -> return $ Return r 
return x = FlowT $ return (Continue x) 


instance MonadTrans FlowT where 
    lift m = FlowT (Continue `liftM` m) 

instance (MonadIO m) => MonadIO (FlowT m) where 
    liftIO m = lift (liftIO m) 

instance (MonadState s m) => MonadState s (FlowT m) where 
    put k = lift (put k) 
    get = lift get 

मेरा इरादा यह था कि खिलौना भाषा में जिसके लिए मैं एक दुभाषिया विकसित कर रहा हूं, आप किसी भी समय किसी अभिव्यक्ति के साथ वापस कॉल करके फ़ंक्शन से वापस लौट सकते हैं। अब जब मैं फ़ंक्शन के आमंत्रण की व्याख्या करने के लिए कोड लिख रहा हूं, तो मुझे इस मोनड में दृश्यों के पीछे पारित प्रवाह मूल्य निकालने की आवश्यकता है। मैं IState() के खिलाफ पैटर्न मिलान नहीं कर सकता क्योंकि इसमें आईओ शामिल है। मुझे जिस फ़ंक्शन की ज़रूरत है, उसे उसी तरह काम करना चाहिए जिस पर राज्य के काम मिलते हैं - मैं इसे कॉल करता हूं और जांच सकता हूं कि कुछ मूल्य लौटाया जा रहा है या नहीं, और यदि हां, तो मुझे यह नहीं मिलता है, अगर कोई नहीं कहता कि कुछ विशेष मूल्य प्रकार का मूल्य वापस आ गया है या कुछ । यह कैसे करना है?

उत्तर

8
मूल्य पर पैटर्न मैच के लिए

, आप, ठीक उसी तरह से आप अपने Monad उदाहरण के भीतर किया दिया इकाई के भीतर अपनी परिणाम आबद्ध करना होगा:

interpret :: FlowT m a -> m a 
interpret flow = do 
    value <- runFlowT flow 
    case value of 
     Continue v -> ... 
     Return r -> ... 

एक पक्ष नोट के रूप में, आप एक विशेष नयापन लाया गया है free monad transformers का मामला, और आप the free package में उनके आधिकारिक कार्यान्वयन को पा सकते हैं।

import Control.Monad.Trans.Free -- from the 'free' package 
import Data.Functor.Constant  -- from the 'transformers' package 

type FlowT = FreeT (Constant Value) 

यह ठीक उसी व्यवहार और एक ही Monad और MonadTrans उदाहरणों के साथ एक isomorphic प्रकार देता है:

विशेष रूप से, अपने FlowT प्रकार समान है।

लेकिन अपने विशिष्ट प्रश्न पर वापस जाएं: नहीं, पहले बेस मोनाड के परिणाम को बाध्य किए बिना मूल्य पर पैटर्न मिलान का कोई तरीका नहीं है।

+0

मुझे नहीं पता कि यह कैसे संभव है, लेकिन मुझे पूरा यकीन है कि मैंने पहले यह कोशिश की है और यह काम नहीं कर रहा है। हालांकि, अपनी पोस्ट पढ़ने और मेरे कोड को फिर से लिखने के बाद मैं जादूगर रूप से इसे काम करने के लिए मिला। मुझे नहीं पता कि क्या गलत था :) मुझे नियंत्रण के बारे में पता नहीं था। मोनाड। ट्रान्स। हालांकि फ्री। मदद के लिए धन्यवाद –

+0

यह मेरे साथ भी होता है, चिंता न करें। :) –

संबंधित मुद्दे