मैं समझने के लिए संघर्ष कर रहा हूं कि इन दो स्निपेट तथाकथित "गरीब व्यक्ति के सख्त विश्लेषण" के तहत अलग-अलग परिणाम क्यों उत्पन्न करते हैं।डेटा और नए प्रकार के बीच आलस्य/कठोरता
पहला उदाहरण का उपयोग करता है data
(एक सही अनुप्रयोगी उदाहरण मानते हुए):
data Parser t a = Parser {
getParser :: [t] -> Maybe ([t], a)
}
> getParser (pure (,) <*> literal ';' <*> undefined) "abc"
*** Exception: Prelude.undefined
दूसरा newtype
उपयोग करता है। वहाँ कोई अन्य अंतर है:
newtype Parser t a = Parser {
getParser :: [t] -> Maybe ([t], a)
}
> getParser (pure (,) <*> literal ';' <*> undefined) "abc"
Nothing
literal x
एक पार्सर कि इनपुट में से एक टोकन लेने वाली सफल होता है अपने तर्क पहले टोकन से मेल खाता है। तो इस उदाहरण में, यह ;
से a
से मेल नहीं खाता है। हालांकि, data
उदाहरण अभी भी देखता है कि अगला पार्सर अपरिभाषित है, जबकि newtype
उदाहरण नहीं है।
मैंने, this, और this पढ़ा है, लेकिन यह समझने के लिए पर्याप्त नहीं है कि पहला उदाहरण क्यों अनिर्धारित है। ऐसा लगता है कि इस उदाहरण में, newtype
data
से आलसी है, उत्तर के विपरीत के विपरीत। (कम से कम one other person भी इससे उलझन में है)।
data
से newtype
पर स्विचिंग क्यों इस उदाहरण की परिभाषा को बदलती है?
यहाँ एक और बात यह है कि मुझे पता चला है: इस अनुप्रयोगी उदाहरण के साथ, आउटपुट ऊपर data
पार्सर अपरिभाषित:
instance Applicative (Parser s) where
Parser f <*> Parser x = Parser h
where
h xs =
f xs >>= \(ys, f') ->
x ys >>= \(zs, x') ->
Just (zs, f' x')
pure a = Parser (\xs -> Just (xs, a))
जबकि इस उदाहरण के साथ, data
पार्सर ऊपर करता नहीं उत्पादन अपरिभाषित (यह मानते हुए Parser s
के लिए एक सही मोनाड उदाहरण):
instance Applicative (Parser s) where
f <*> x =
f >>= \f' ->
x >>= \x' ->
pure (f' x')
pure = pure a = Parser (\xs -> Just (xs, a))
पूर्ण कोड स्निपेट:
import Control.Applicative
import Control.Monad (liftM)
data Parser t a = Parser {
getParser :: [t] -> Maybe ([t], a)
}
instance Functor (Parser s) where
fmap = liftM
instance Applicative (Parser s) where
Parser f <*> Parser x = Parser h
where
h xs = f xs >>= \(ys, f') ->
x ys >>= \(zs, x') ->
Just (zs, f' x')
pure = return
instance Monad (Parser s) where
Parser m >>= f = Parser h
where
h xs =
m xs >>= \(ys,y) ->
getParser (f y) ys
return a = Parser (\xs -> Just (xs, a))
literal :: Eq t => t -> Parser t t
literal x = Parser f
where
f (y:ys)
| x == y = Just (ys, x)
| otherwise = Nothing
f [] = Nothing
इस तरह के एक प्रश्न पूछते समय, यह सामान्य रूप से बेहतर होता है यदि आप सभी प्रासंगिक कोड शामिल करते हैं, यदि यह फिट करने के लिए पर्याप्त छोटा है (इसमें 'फंक्टर' और 'मोनाड' उदाहरण, और 'शाब्दिक' शामिल हैं), ताकि लोग डॉन करें यह अनुमान लगाने की ज़रूरत नहीं है कि आपने कार्यों को कैसे लिखा है (जैसा कि आपने बताया है, यहां तक कि छोटे बदलाव भी व्यवहार में अंतर डाल सकते हैं)। – shachaf
@shachaf असली सवाल यहां नहीं है "मैं अपना कोड कैसे ठीक करूं?" - मैंने पहले ही ऐसा किया है - लेकिन "सख्तता/आलस्य के संबंध में 'डेटा' और 'न्यूटाइप' के बीच क्या अंतर है?" क्षमा करें अगर यह सवाल से स्पष्ट नहीं है। –
हां, लेकिन फिर भी, हम यह बताए बिना कोड को कैसा दिखने के बिना आपके कोड के साथ क्या चल रहा था? – shachaf