2015-08-17 11 views
6

मैं एक साधारण कंसोल शतरंज गेम लिखकर हास्केल सीखने की कोशिश कर रहा हूं। यह एक शतरंज बोर्ड प्रदर्शित करता है और SAN notation में मानक इनपुट से चाल प्राप्त करता है। यहाँ मैं अब तक क्या कर लिया है:हास्केल में रनटाइम त्रुटियों को कैसे संभालें?

import System.IO 
import Chess 
import Chess.FEN 

main = do 
    putStrLn "Welcome to Console Chess!" 
    putStrLn $ show defaultBoard 
    gameLoop defaultBoard 

gameLoop board = do 
    putStr "Your move: " 
    hFlush stdout 
    move <- getLine 
    let newBoard = moveSAN move board 
    case newBoard of 
    Left _ -> do 
    putStrLn "Invalid move, try again..." 
    gameLoop board 
    Right b -> do 
    putStrLn $ show b 
    gameLoop b 

समस्या यह है कि moveSAN कार्य करने के लिए कॉल कभी कभी कार्यक्रम दुर्घटनाओं, खेल में किए गए सभी प्रगति को खोने है। उदाहरण के लिए, पर Enter दबा "आपका कदम:" शीघ्र निर्माण करता है:

Your move: 
cchess: Prelude.head: empty list 

अन्यथा, एक दो अंकों की संख्या में प्रवेश का उत्पादन:

Your move: 11 
cchess: Error in array index 

दो अवधियों में प्रवेश कर देता है:

Your move: .. 
cchess: Char.digitToInt: not a digit '.' 

मैं इन त्रुटियों को पकड़ना चाहता हूं और उपयोगकर्ता को सूचित करना चाहता हूं कि उनके द्वारा दर्ज किए गए कदम मान्य SAN नोटेशन में नहीं हैं। मैं उसे कैसे कर सकता हूँ?

+0

आपका कोड सही है। यह आपके द्वारा उपयोग की जा रही chesshs लाइब्रेरी में एक बग है। खराब इनपुट पर इसे 'बाएं नोपर्स' वापस करना चाहिए, लेकिन इसके बजाय यह 'हेड' और 'digitToInt' जैसे आंशिक कार्यों के उपयोग के कारण दुर्घटनाग्रस्त हो जाता है :( –

+0

मैं सहमत हूं, समाधान कुल कार्य है, जो केवल स्वयं को बना सकता है कार्यों को पूरा करने के लिए आपको कैच स्टेटमेंट में लाइब्रेरी कॉल को लपेटने की आवश्यकता होगी ... –

+0

"आपको कैच स्टेटमेंट में लाइब्रेरी कॉल को लपेटने की आवश्यकता होगी" मैं यह कैसे कर सकता हूं? – hedgie

उत्तर

7

एक आदर्श दुनिया में, आप head जैसे कार्यों से बचेंगे और रनटाइम त्रुटियां नहीं हैं। रनटाइम त्रुटियां मूल रूप से अजीब हैं, खासकर हास्केल में।

इस मामले में, आप रनटाइम त्रुटि को पकड़ना चाहते हैं। यदि आप इसे Maybe में बदलने की सामग्री रखते हैं, तो आप spoon पैकेज का उपयोग कर सकते हैं।

हास्केल में अपवाद आलसी के लिए सूक्ष्म धन्यवाद हैं। विशेष रूप से, यदि आप उस संरचना के उस हिस्से का मूल्यांकन नहीं करते हैं जिसमें अपवाद है, तो यह आग नहीं लगेगा। यह दो अलग अलग कार्यों के साथ spoon में नियंत्रित किया जाता है:

  • spoon है, जो एक संरचना गहरा का मूल्यांकन करता है, लेकिन एक विशेष typeclass
  • teaspoon जो केवल weak head normal form
  • के रास्ते से अपने संरचना भाग का मूल्यांकन करता है का एक उदाहरण की आवश्यकता है

आपके मामले में, मुझे लगता है कि teaspoon ठीक होना चाहिए। साथ पार्स का परिणाम देखने का प्रयास करें:

teaspoon (moveSAN move board) 

जो आपको एक Maybe मूल्य देना चाहिए।

यदि यह काम नहीं करता है, तो इसका मतलब है कि आपको अपवाद को हिट करने के लिए अधिक संरचना का मूल्यांकन करने की आवश्यकता है। यह Board की तरह लग रहा typeclass गहरा spoon साथ यह मूल्यांकन करने के लिए की जरूरत को लागू नहीं करता, इसलिए आपका सर्वश्रेष्ठ दांव थोड़ा hacky है: show के परिणाम पर spoon का उपयोग करें:

spoon (show $ moveSAN move board) 

यह आपको एक Maybe String दे देंगे। यदि यह Just है, तो चाल सही ढंग से पार्स की गई है; अगर यह Nothing है, तो एक त्रुटि हुई थी।

यह ध्यान देने योग्य है कि spoon पैकेज वास्तव में बहुत कुछ नहीं करता है: प्रत्येक कार्य में केवल a couple of lines है।किसी बिंदु पर, यह पता लगाने लायक है कि हास्केल में अपवादों को कैसे संभाला जाए, लेकिन अब spoon बस थोड़ा और सुविधाजनक है और आपके लिए ठीक से काम करना चाहिए।

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