2016-11-19 2 views
6

मुझे पता है कि मैं इस तरह के एसएमएल में वाई-संयोजक लिख सकता हूं: सर्कुलरिटी के कारण टाइप मिस्चैच को बाईपास करने के लिए पहले एक नया डेटाटाइप घोषित करें।वाईएम-संयोजक मानकएमएल

val Y = fn f => (fn x => fn a => f (unroll x x) a) 
      (Roll (fn x => fn a => f (unroll x x) a))) 

तो आप कर चुके हैं, तो आप इसे इस तरह से उपयोग कर सकते हैं:

val f = Y (fn f => fn n => if n = 0 then 1 else n * f (n-1)) 

मेरा प्रश्न है

datatype 'a mu = Roll of ('a mu -> 'a) 
val unroll = fn Roll x => x 

अब आप आसानी से y-Combinator परिभाषित कर सकते हैं: क्या एसएमएल में वाई-संयोजक को लागू करने के अन्य तरीके हैं?

उत्तर

5

आप निश्चित रूप से अंतर्निहित रिकर्सन का उपयोग कर सकते हैं, उदा।

fun Y f = f (fn x => Y f x) 

या

fun Y f x = f (Y f) x 

तुम भी एक डेटाप्रकार के रूप में एक ही तरह से अपवाद का उपयोग कर सकते हैं, लेकिन केवल monomorphically:

exception Roll of exn -> int -> int 
val unroll = fn Roll x => x 
fun Y f = (fn x => fn a => f (unroll x x) a) (Roll (fn x => fn a => f (unroll x x) a)) 

लेकिन मैं संदर्भ के साथ विश्वास है कि के बारे में यह शामिल किया गया।

संपादित करें: असल में, आप यह बहुरूपी एक स्थानीय अपवाद का उपयोग करके कर सकते हैं:

fun Y f : 'a -> 'b = 
    let 
    exception Roll of exn -> 'a -> 'b 
    val unroll = fn Roll x => x 
    in 
    (fn x => fn a => f (unroll x x) a) (Roll (fn x => fn a => f (unroll x x) a)) 
    end 
+0

आप नहीं कर सकते हैं, के बाद से स्वयं अनुप्रयोग है कि के लिए आवश्यक एक पुनरावर्ती प्रकार की आवश्यकता है। –

+0

@NaCl अच्छी तरह से, आप कर सकते हैं, क्योंकि "मजेदार" एक 'व्युत्पन्न' का व्युत्पन्न रूप है, लेकिन यह 'मजेदार' का उपयोग करने के बराबर होगा। – matt