2016-07-21 8 views
6

इस IO कोड को देखते हुए:तीसरा मोनॉयड लॉ और आईओ?

Prelude> let e = return() :: IO() 
Prelude> e `mappend` e 
Prelude> let y = e `mappend` e 
Prelude> :t y 
y :: IO() 

संपादित जाहिर है, के रूप में मैं समझता हूँ, IO एक Monoid उदाहरण है।

हालांकि, मोनॉयड तीसरे कानून का पालन करने के लिए निम्नलिखित मूल्यांकन true पर नहीं होना चाहिए?

Prelude> e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 

<interactive>:14:1: error: 
    * No instance for (Eq (IO())) arising from a use of `==' 
    * In the expression: 
     e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 
     In an equation for `it': 
      it = e `mappend` (e `mappend` e) == (e `mappend` e) `mappend` e 

उत्तर

11

The third monoid law कहा गया है कि e <> (e <> e) = (e <> e) <> e (mappend के लिए आसान करने के लिए प्रकार इन्फ़िक्स ऑपरेटर का उपयोग करने के लिए), नहीं कि e <> (e <> e) == (e <> e) <> e (ध्यान दें = बनाम ==)।

यह एक तुल्यता व्यक्त है - वास्तव में, व्यक्त कि mappend साहचर्य होना चाहिए - सभी Monoid नहीं की मांग भी Eq typeclass, जहां == से आता है के उदाहरण होना चाहिए।

यह कहने का एक और तरीका: यह mappend फ़ंक्शन के व्यवहार के बारे में एक उच्च स्तरीय विचार व्यक्त कर रहा है, जो वैध हास्केल कोड प्रस्तुत नहीं करता है जिसे विशेष रूप से किसी भी चीज़ का मूल्यांकन करना चाहिए।

कुछ प्रकार है कि कर रहे हैं Monoid रों - उदाहरण के लिए [()] की तरह, - यह भी एक Eq उदाहरण के लिए होता है। लेकिन कुछ (जैसे IO() उदाहरण यहां) नहीं, और यह ठीक है।

Sidenote: यह वास्तव में, भावना IO देने के लिए एक Eq उदाहरण नहीं है, क्योंकि यह निर्धारित करने के लिए असंभव पर निकट है अगर एक निश्चित IO() एक और IO() के बराबर है। putStrLn "3" "बराबर" से print 3 है? दोनों के पास एक ही अवलोकन प्रभाव पड़ता है, लेकिन कैसे चलने वाला समय सामान्य समय में निर्धारित कर सकता है? और आप यह नहीं कह सकते कि "वे बराबर हैं यदि वे समान मूल्य उत्पन्न करते हैं," तो फिर == का रिटर्न प्रकार IO Bool होना चाहिए, और यह Eq के लिए सही हस्ताक्षर नहीं है। इसलिए हम IOEq उदाहरण नहीं देते हैं, और यह ठीक है - मैं इस तरह का एक उदाहरण उपयोगी होने के उचित उदाहरण के साथ नहीं आ सकता।

भी ध्यान रखें कि "IO" एक Monoid उदाहरण नहीं है (यह गलत तरह, वैसे भी है)। mappend जिसका उपयोग आप कर रहे हैं Monoid a => Monoid (IO a) — के लिए उदाहरण से आता है, आईओ रेसिपी जो कि Monoid एस हैं। IO का Monoid उदाहरण अंतर्निहित Monoid उदाहरण पर बस "पिग्गी-बैक" उदाहरण है।

+5

एक वैध, सहजता से सही 'ईक (आईओ ए)' उदाहरण * जरूरी * उपयोगी होगा, अगर इसे लिखना संभव था। लेकिन एलन ट्यूरिंग उसकी कब्र में बैठेगी और यदि आप कोशिश करते हैं तो आपको एक जीभ-झटके दे देंगे। – dfeuer

+1

@ dfeuer मुझे समस्या नहीं दिखाई दे रही है। आखिरकार, हमारे पास 'eq [a]' उदाहरण है। –

+0

@ReinHenrichs, आप एक बिंदु है! – dfeuer

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