मैं ओओपी के वर्षों के बाद हास्केल सीख रहा हूं।हास्केल में राज्य के साथ "वेब मकड़ी" कैसे डिजाइन करें?
मैं कुछ कार्यों और राज्य के साथ एक गूंगा वेब मकड़ी लिख रहा हूं।
मुझे यकीन नहीं है कि एफपी दुनिया में इसे कैसे किया जाए।
OOP दुनिया में इस मकड़ी इस तरह डिजाइन किया जा सकता है (उपयोग के आधार पर):
Browser b = new Browser()
b.goto(“http://www.google.com/”)
String firstLink = b.getLinks()[0]
b.goto(firstLink)
print(b.getHtml())
इस कोड को लोड http://www.google.com/, तो "क्लिक" पहले लिंक, दूसरे पृष्ठ का भार सामग्री और फिर सामग्री प्रिंट करता है।
class Browser {
goto(url: String) : void // loads HTML from given URL, blocking
getUrl() : String // returns current URL
getHtml() : String // returns current HTML
getLinks(): [String] // parses current HTML and returns a list of available links (URLs)
private _currentUrl:String
private _currentHtml:String
}
यह possbile 2 या "ब्राउज़र" के लिए एक बार में, अपनी अलग राज्य के साथ है:
Browser b1 = new Browser()
Browser b2 = new Browser()
b1.goto(“http://www.google.com/”)
b2.goto(“http://www.stackoverflow.com/”)
print(b1.getHtml())
print(b2.getHtml())
प्रश्न: बताएंगे कि कैसे आप scracth से हास्केल में ऐसी बात डिजाइन होगा (ब्राउज़र कई स्वतंत्र उदाहरण होने की संभावना के साथ एपीआई के साथ)? कृपया, कोड स्निपेट दें।
नोट: सादगी के लिए, getLinks() फ़ंक्शन (इसके छोटे और दिलचस्प नहीं) पर विवरण छोड़ें।
भी मान लेते हैं एक API समारोह
getUrlContents :: String -> IO String
HTTP कनेक्शन को खोलता है और इस URL का एक HTML देता है कि वहाँ करते हैं।
अद्यतन: क्यों राज्य के लिए (या नहीं हो सकता है)?
एपीआई में केवल "लोड-एंड-पार्स परिणाम" नहीं बल्कि अधिक फ़ंक्शन हो सकते हैं।
मैंने जटिलता से बचने के लिए उन्हें नहीं जोड़ा।
इसके अलावा यह वास्तविक ब्राउज़र व्यवहार को अनुकरण करने के लिए प्रत्येक अनुरोध के साथ HTTP रेफरर हेडर और कुकीज़ के बारे में भी ध्यान रख सकता है। पहले इनपुट क्षेत्र
- ओपन http://www.google.com/
- प्रकार "हास्केल":
इस परिदृश्य पर विचार करें "3"
- वर्तमान पृष्ठ का HTML प्रिंट करें ("हैकेल" के लिए Google परिणाम पृष्ठ 3)
हाथों पर इस तरह एक परिदृश्य के बाद, मैं एक डेवलपर के रूप में यह हस्तांतरण करने के लिए अधिक से अधिक निकट कोड करने के लिए करना चाहते हैं:
Browser b = new Browser()
b.goto("http://www.google.com/")
b.typeIntoInput(0, "haskell")
b.clickButton("Google Search") // b.goto(b.finButton("Google Search"))
b.clickLink("2") // b.goto(b.findLink("2"))
b.clickLink("3")
print(b.getHtml())
इस परिदृश्य के लक्ष्य के बाद पिछले पृष्ठ के HTML पाने के लिए है संचालन का एक सेट। कोड कॉम्पैक्ट रखना एक और कम दृश्य लक्ष्य है।
यदि ब्राउज़र का कोई राज्य है, तो यह HTTP रेफरर हेडर और कुकीज़ भेज सकता है जबकि सभी मैकेनिक्स को अपने अंदर छुपाकर और अच्छा एपीआई दे रहा है।
यदि ब्राउज़र का कोई राज्य नहीं है, तो डेवलपर सभी मौजूदा यूआरएल/एचटीएमएल/कुकीज़ के आसपास गुजरने की संभावना है - और यह परिदृश्य कोड में शोर जोड़ता है।
नोट: मुझे लगता है कि हैस्केल में एचटीएमएल को छीनने के लिए पुस्तकालयों के बाहर हैं, लेकिन मेरा इरादा एचटीएमएल को स्क्रैप नहीं करना था, लेकिन सीखें कि कैसे इन "ब्लैक बॉक्सिंग" चीजें हास्केल में ठीक से डिजाइन की जा सकती हैं।
शानदार। .... – oshyshko
ध्यान दें कि ब्राउज़रएक्शन मोनैड पहले से मौजूद है: http://hackage.haskell.org/packages/archive/HTTP/4000.0.8/doc/html/Network-Browser.html – jrockway
यह भी ध्यान दें कि 'फ़्लिप मानचित्र एम' 'forM' कहा जाता है। – BMeph