2011-10-26 13 views
5

मुझे एक त्वरित प्रश्न है। हास्केल 57 - Undefined variable "f" error मुझ पर फेंक रहा है और मुझे नहीं पता कि क्यों। यदि आप इसे देख सकते हैं तो मैं इसकी सराहना करता हूं।अपरिभाषित वैरिएबल, हास्केल

कोड:

eval :: Expr -> Environment -> Float 
eval expr env = eval' expr 
    where 
    eval' :: Expr-> Float 
    eval' (Num num) = num 
    eval' (App app exprs) = foldl1 (f) (map eval' exprs) -- **Line 57** 
    eval' (Id id) = 5 
     where 
     f = getFunctionForApp app     -- **f is here** 
     getFunctionForApp :: String -> (Float->Float->Float) 
     getFunctionForApp "+" = (+) 
     getFunctionForApp "-" = (-) 
     getFunctionForApp "*" = (*) 
     getFunctionForApp "/" = (/) 
     getIdVal :: String -> Environment -> Float 
     getIdVal id ((curId, val):envrs) 
      |curId == id = val 
      | otherwise = getIdVal id envrs 

प्रकार परिभाषा:

data Expr = Num Float | Id String | App String [ Expr ] 
      deriving (Eq, Ord, Show) 
type Environment = [ (String, Float) ] 
+3

मैं ईमानदारी से जवाब नहीं जानता लेकिन मैंने सोचा कि जहां ब्लॉक को स्टेटमेंट के बाद आना पड़ा था। दूसरे शब्दों में, क्या आपने पूरी तरह से एक लाइन को अवरुद्ध करने की कोशिश की है? – Ramy

उत्तर

9

जहां ब्लॉक केवल मामला सीधे यह पहले, eval' समारोह के सभी मामलों के लिए नहीं करने के लिए लागू होता है। तो feval' (Id id) = 5 में परिभाषित किया गया है (लेकिन उनका उपयोग नहीं), लेकिन यह इस आप सीधे लाइन 57.

+0

या आखिरी "eval" लाइन के ठीक बाद "f = ..." डालें - जहां एक ब्लॉक दूसरे स्थान पर घिरा हुआ है जहां ब्लॉक मेरे लिए अजीब लगता है, हालांकि शायद कुछ मामलों में इसके लिए अच्छे कारण हैं। – MatrixFrog

+0

@MatrixFrog: हां, कभी-कभी घोंसले के लिए बहुत अच्छे कारण होते हैं; यदि आप उदाहरण के लिए 'स्थिर तर्क परिवर्तन' मैन्युअल रूप से लागू करते हैं। यहां, नेस्टेड 'कहां' का उपयोग पैटर्न में बाध्य मूल्य का उपयोग करके किसी चीज़ के लिए संक्षिप्त नाम बनाने के लिए किया जाता है, जो कि एक आम उपयोग भी है। –

3

वास्तव में क्या sepp2k कहा के बाद जहां ब्लॉक को स्थानांतरित करने की जरूरत है ठीक करने के लिए लाइन 57. में दायरे में नहीं है। इस मामले में, हालांकि, मैं बस 57 और 58 लाइनों को स्वैप करना पसंद करूंगा, इसलिए whereeval' के समीकरणों को विभाजित किए बिना सही समीकरण से जुड़ा हुआ है, जो अधिक पठनीय है।

या बिल्कुल f का उपयोग नहीं करते, यह

eval' (App app exprs) = foldl1 (getFunctionOrApp app) (map eval' exprs) 
eval' (Id id) = 5 

getFunctionOrApp :: String -> (Float -> Float -> Float) 
getFunctionOrApp "+" = ... 

चलती getFunctionOrApp (और getIdVal) एक ही स्तर के whereeval' रूप में, यह यहां तक ​​कि उन्हें शीर्ष स्तर पर परिभाषित करने के लिए उचित हो सकता है।

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