यदि आप फ़ंक्शन के डोमेन की गणना कर सकते हैं और समानता के लिए सीमा के तत्वों की तुलना कर सकते हैं, तो आप कर सकते हैं - बल्कि सीधे तरीके से। गणना करने से मेरा मतलब है उपलब्ध सभी तत्वों की एक सूची। मैं Haskell से चिपके रहूँगा, क्योंकि मुझे पता नहीं है कि Ocaml (या यहाँ तक कि इसे ठीक से कैपिटल कैसे किया जाता है ;-)
आप जो करना चाहते हैं, वह डोमेन के तत्वों के माध्यम से चलाया जाता है और देखें कि क्या वे उस श्रेणी के तत्व के बराबर हैं, जिसे आप उल्टा करने की कोशिश कर रहे हैं, और जो काम करता है उसे पहले करें:
inv :: Eq b => [a] -> (a -> b) -> (b -> a)
inv domain f b = head [ a | a <- domain, f a == b ]
चूंकि आपने कहा है कि f
यह एक आपत्ति है, इसलिए केवल एक और ऐसा एक ही तत्व होना चाहिए। चाल, निश्चित रूप से, यह सुनिश्चित करना है कि डोमेन की आपकी गणना वास्तव में सभी तत्वों तक सीमित समय में पहुंचती है । आप से एक द्विभाजन को उलटने की कोशिश कर रहे हैं Integer
करने के लिए Integer
, का उपयोग कर [0,1 ..] ++ [-1,-2 ..]
काम नहीं करेगा आप ऋणात्मक संख्याओं के लिए कभी नहीं मिलेगा के रूप में। लगातार, inv ([0,1 ..] ++ [-1,-2 ..]) (+1) (-3)
कभी भी मूल्य नहीं मिलेगा।
हालाँकि, 0 : concatMap (\x -> [x,-x]) [1..]
काम करेगा, क्योंकि यह निम्न क्रम में पूर्णांकों के माध्यम से चलता है [0,1,-1,2,-2,3,-3, and so on]
। वास्तव में inv (0 : concatMap (\x -> [x,-x]) [1..]) (+1) (-3)
तुरंत रिटर्न -4
!
नियंत्रण । मोनाड । ओमेगा पैकेज एक अच्छे तरीके से ट्यूपल्स वगैरह की सूचियों के माध्यम से चलाने में आपकी सहायता कर सकता है; मुझे यकीन है कि इस तरह और भी पैकेज हैं - लेकिन मैं उन्हें नहीं जानता।
बेशक, यह दृष्टिकोण कम-भौंह और जानवर-बल है, न कि बदसूरत और अक्षम का उल्लेख करने के लिए! इसलिए मैं आपके प्रश्न के अंतिम भाग पर कुछ टिप्पणी के साथ समाप्त कर दूंगा, कि किस तरह से 'विशेषण' लिखें। हास्केल की प्रकार प्रणाली यह साबित करने के लिए नहीं है कि एक फ़ंक्शन एक आक्षेप है - आप वास्तव में उसके लिए एजडा जैसा कुछ चाहते हैं - लेकिन यह आप पर भरोसा करने के लिए तैयार है।
(चेतावनी: अनुपलब्ध कोड इस प्रकार है)
तो क्या आप Bijection
प्रकार a
और के बीच में से एक डेटा टाइप परिभाषित कर सकते हैं b
:
data Bi a b = Bi {
apply :: a -> b,
invert :: b -> a
}
कई स्थिरांक के साथ (जहाँ आप कह सकते हैं कि 'मुझे पता है कि वे पूर्वाग्रह हैं!') जैसे आप चाहते हैं, जैसे:
notBi :: Bi Bool Bool
notBi = Bi not not
add1Bi :: Bi Integer Integer
add1Bi = Bi (+1) (subtract 1)
और स्मार्ट कॉम्बीनेटरों की एक जोड़ी, जैसे:
idBi :: Bi a a
idBi = Bi id id
invertBi :: Bi a b -> Bi b a
invertBi (Bi a i) = (Bi i a)
composeBi :: Bi a b -> Bi b c -> Bi a c
composeBi (Bi a1 i1) (Bi a2 i2) = Bi (a2 . a1) (i1 . i2)
mapBi :: Bi a b -> Bi [a] [b]
mapBi (Bi a i) = Bi (map a) (map i)
bruteForceBi :: Eq b => [a] -> (a -> b) -> Bi a b
bruteForceBi domain f = Bi f (inv domain f)
मुझे लगता है कि आप तब कर सकते हैं invert (mapBi add1Bi) [1,5,6]
और प्राप्त कर सकते हैं [0,4,5]
। यदि आप अपने कॉम्बीनेटरों को स्मार्ट तरीके से चुनते हैं, तो मुझे लगता है कि आपको Bi
हाथ से लगातार लिखने की संख्या काफी सीमित हो सकती है।
आखिरकार, यदि आप जानते हैं कि कोई फ़ंक्शन एक आपत्ति है, तो आपको उम्मीद है कि आपके सिर में उस तथ्य का एक प्रूफ-स्केच होगा, जिसे करी-हावर्ड समरूपता एक कार्यक्रम में बदलने में सक्षम होना चाहिए :-)
f x = 1
, 1 का विलोम पूर्णांकों का एक सेट है और किसी अन्य चीज का व्युत्क्रम एक खाली सेट है। इसके बावजूद कि कुछ जवाब क्या कहते हैं, फ़ंक्शन का विशेषण नहीं होना सबसे बड़ी समस्या नहीं है।