हास्केल के संदर्भ में वाई कॉम्बीनेटर को समझाते समय, यह आमतौर पर नोट किया जाता है कि अपने पुनरावर्ती प्रकार के कारण स्ट्रेट-फॉरवर्ड कार्यान्वयन हास्केल में टाइप-चेक नहीं करेगा।
उदाहरण के लिए, रोज़ेटाकोड से :
The obvious definition of the Y combinator in Haskell canot be used
because it contains an infinite recursive type (a = a -> b). Defining
a data type (Mu) allows this recursion to be broken.
newtype Mu a = Roll { unroll :: Mu a -> a }
fix :: (a -> a) -> a
fix = \f -> (\x -> f (unroll x x)) $ Roll (\x -> f (unroll x x))
और वास्तव में, "स्पष्ट" परिभाषा चेक टाइप नहीं करती है:
λ> let fix f g = (\x -> \a -> f (x x) a) (\x -> \a -> f (x x) a) g
<interactive>:10:33:
Occurs check: cannot construct the infinite type:
t2 = t2 -> t0 -> t1
Expected type: t2 -> t0 -> t1
Actual type: (t2 -> t0 -> t1) -> t0 -> t1
In the first argument of `x', namely `x'
In the first argument of `f', namely `(x x)'
In the expression: f (x x) a
<interactive>:10:57:
Occurs check: cannot construct the infinite type:
t2 = t2 -> t0 -> t1
In the first argument of `x', namely `x'
In the first argument of `f', namely `(x x)'
In the expression: f (x x) a
(0.01 secs, 1033328 bytes)
Ocaml में एक ही सीमा मौजूद है:
utop # let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g;;
Error: This expression has type 'a -> 'b but an expression was expected of type 'a
The type variable 'a occurs inside 'a -> 'b
हालाँकि, Ocaml में, कोई -rectypes
स्विच में पास करके पुनरावर्ती प्रकारों की अनुमति दे सकता है :
-rectypes
Allow arbitrary recursive types during type-checking. By default, only recursive
types where the recursion goes through an object type are supported.
का उपयोग करके -rectypes
, सब कुछ काम करता है:
utop # let fix f g = (fun x a -> f (x x) a) (fun x a -> f (x x) a) g;;
val fix : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
utop # let fact_improver partial n = if n = 0 then 1 else n*partial (n-1);;
val fact_improver : (int -> int) -> int -> int = <fun>
utop # (fix fact_improver) 5;;
- : int = 120
टाइप सिस्टम और प्रकार के अनुमान के बारे में उत्सुक होने के नाते, यह कुछ ऐसे प्रश्न उठाता है जिनका मैं अभी भी उत्तर नहीं दे पा रहा हूं।
- सबसे पहले, प्रकार चेकर प्रकार के साथ कैसे आता है
t2 = t2 -> t0 -> t1
? उस प्रकार के साथ आने से, मुझे लगता है कि समस्या यह है कि प्रकार (t2
) सही पक्ष पर खुद को संदर्भित करता है? - दूसरा, और शायद सबसे दिलचस्प, हस्केल / ओकेमेल टाइप सिस्टमों को इसे खत्म करने का कारण क्या है? मुझे लगता है कि वहाँ है एक अच्छा कारण के बाद से OCaml भी डिफ़ॉल्ट भले ही यह द्वारा यह अनुमति नहीं दी जाएगी कर सकते हैं पुनरावर्ती प्रकार के साथ सौदा है, तो दिए गए
-rectypes
स्विच।
यदि ये वास्तव में बड़े विषय हैं, तो मैं प्रासंगिक साहित्य की ओर संकेत करता हूँ।