क्यों `प्रिंट <$> (प्रिंट" हैलो ")` प्रिंट "हैलो"?


14

जब की गणना IO (IO ()), दोनों (IO ())और ()गणना की जाती है, तो क्यों

main :: IO (IO ())
main = print <$> (print "Hello, World!")

प्रिंट

"Hello, World!"

नहीं

IO "Hello, World!" -- ??
"Hello, World!"

3
मूल रूप से fmap print (print "Hello World")यह पहले पैरामीटर, printफ़ंक्शन, के परिणाम पर लागू होता है print "Hello World"। यह केवल कार्रवाई करने के print ()बाद आह्वान करने के बराबर print "Hello World"है।
रेडू

@Redu यह सही है, लेकिन ध्यान दें कि print ()कभी भी मंगलाचरण का मूल्यांकन नहीं किया जाता है, और न ही इसकी कार्रवाई की जाती है (जो स्टेकआउट ()पर प्रिंट होती है)। तो, "के print ()बाद आह्वान ..." थोड़ा भ्रामक (IMO) है।
ची

जवाबों:


21
main :: IO (IO ())
main = print <$> (print "Hello, World!")

समतुल्य है, मोनड कानूनों के लिए धन्यवाद

main :: IO (IO ())
main = do 
   result <- print "Hello, World!"
   return (print result)

अब, printहमेशा ()परिणाम के रूप में लौटता है , इसलिए पूरे कोड के बराबर है

main :: IO (IO ())
main = do 
   _ <- print "Hello, World!"
   return (print ())

अंत में, परिणाम mainकेवल त्याग दिया जाता है। यही है, अंतिम पंक्ति return (putStrLn "this is ignored")और समान प्रभाव हो सकता है।

इसलिए कोड केवल पहले निष्पादित करेगा print "Hello, World!"

मैं आपको सलाह दूंगा कि आप हमेशा परिभाषित करें main :: IO ()। हास्केल हमें घोषित करने की अनुमति देता है main :: IO AnyTypeHere, लेकिन यह (आईएमओ) भ्रमित है।

मैं आपको उपयोग करने की सलाह भी दूंगा putStrLn, और printतार नहीं छापने के लिए, क्योंकि बाद वाली बोली और पूरे स्ट्रिंग से बच जाएगी।


5
मैं जोड़ूंगा कि f <$> a ≡ a >>= \r -> return $ f rइस स्थिति के लिए सिर्फ एक विशिष्ट बात नहीं है, लेकिन वास्तव में किसी भी सन्यासी के लिए है।
लेफ्टनैबआउट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.