2013-02-23 15 views
8

मैं हास्केल के साथ डेटाबेस का उपयोग करने के लिए एक सरल और सहज तरीके से आने का प्रयास कर रहा हूं। मैंने इस कोड को Yesod book से लिया है और इसे साफ़ करने की कोशिश की है ताकि इसे समझना और उपयोग करना आसान हो।हास्केल/पर्सिस्टेंट-स्क्लाइट: "कोई उदाहरण नहीं है (Control.Monad.Trans.Resource.MonadResource IO)"

{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-} 
{-# LANGUAGE GADTs, FlexibleContexts #-} 

import Database.Persist 
import Database.Persist.Sqlite (withSqliteConn, runSqlConn, runMigration) 
import Database.Persist.TH (share, mkPersist, mkMigrate, sqlSettings, persist) 

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| 
Person        -- Table name 
    name String      -- String value 
    age Int Maybe     -- Numerical value 
|] 

updateDB x y = withSqliteConn "data.db" $ runSqlConn $ do 
    runMigration migrateAll   -- Creates "Person" table if one doesn't exist 
    insert $ Person x $ Just y  -- Inserts values into .db file 

main = do 
    updateDB "Frank Silver" 40  -- adds name "Frank Silver" and age "40" to data.db file 

इस कोड लगभग काम करता है, लेकिन मैं निम्न त्रुटि जो मैं हल करने में सक्षम नहीं किया गया मिलता है।

No instance for (Control.Monad.Trans.Resource.MonadResource IO) 
     arising from a use of `updateDB' 
    Possible fix: 
     add an instance declaration for 
     (Control.Monad.Trans.Resource.MonadResource IO) 
    In a stmt of a 'do' block: updateDB "Frank Silver" 40 
    In the expression: do { updateDB "Frank Silver" 40 } 
    In an equation for `main': main = do { updateDB "Frank Silver" 40 } 

सही दिशा में मुझे इंगित करने वाले किसी भी सुझाव की सराहना की जाएगी।

+1

आपको 'मुख्य' में 'updateDB' के आस-पास कम से कम 'runResourceT' की आवश्यकता है। मुझे यकीन नहीं है कि यह पर्याप्त होगा, हालांकि। –

+0

लाइन को पुन: लिखने के रूप में runResourceT $ updateDB "फ्रैंक सिल्वर" 40 काम किया! धन्यवाद। शायद आप अपनी टिप्पणी को उत्तर के रूप में पोस्ट करना चाहते हैं? –

+4

मुझे लगातार इस समस्या का उपयोग करके समस्या थी, लेकिन मुझे आईओ गायब होने के लिए मोनाडलॉगर के उदाहरण के साथ भी एक त्रुटि हुई। मैं इसे आशा में छोड़ रहा हूं कि यह किसी अन्य गरीब आत्मा की मदद करता है। कुंजी 'runResourceT का उपयोग करना है। Control.Monad.Logger.runNoLoggingT', जैसा कि MonadLogger IO के उदाहरण को हटा दिया गया है। – Khanzor

उत्तर

8

साथ

main = do 
    updateDB "Frank Silver" 40 

updateDB "Frank Silver" 40 के प्रकार, IO() होने के लिए लगाए गए अनुमान के बाद से है कि main के लिए डिफ़ॉल्ट प्रकार (यह कुछ a के लिए प्रकार IO a होनी चाहिए) है है। लेकिन परिभाषा से, a (शायद a =(), लेकिन मुझे यकीन नहीं है) के लिए इसका प्रकार MonadRescource m => m a होने का अनुमान लगाया गया है, लेकिन मुझे यकीन नहीं है), और instance MonadResource IO नहीं है। तो अगर आप एक IO कार्रवाई करने के लिए updateDB को बदलने के लिए कुछ चाहिए, ऐसा करने के लिए सामान्य तरीके runResourceT, तो

main = runResourceT $ updateDB "Frank Silver" 40 

काम करता है, जो एक m a (यहाँ m = IO) में एक ResourceT m a बदल देती है।

+0

मैं लगभग एक साल तक हास्केल का उपयोग कर रहा हूं और मैं अभी भी सीख रहा हूं कि टाइप सिस्टम का उपयोग कैसे करें। : डी आपकी मदद और उत्तर के लिए फिर से धन्यवाद। –

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