से निपट नहीं सकता हूं, मैं एक हास्केल फ़ंक्शन लिखना चाहता हूं जो फ्लिप की तरह कार्य करता है लेकिन कहीं अधिक सामान्य है और फ़ंक्शन का कोई पैरामीटर अंतिम पैरामीटर बन सकता है। सुविधा के लिए, हम इसका प्रतिनिधित्व करने के लिए pull
का उपयोग करते हैं।मैं एक समारोह लिखना चाहता हूं जो लैम्ब्डा अभिव्यक्तियों से छुटकारा पाने के लिए हास्केल में 'फ्लिप' जैसा है। लेकिन मैं इसके प्रकार
यह निम्न कोड लिखने के लिए आसान है:
Prelude> :t flip --we just call this function a swap
flip :: (a -> b -> c) -> b -> a -> c
Prelude> :t (flip.) --we just call this function a swap
(flip.) :: (a -> a1 -> b -> c) -> a -> b -> a1 -> c
Prelude> :t ((flip.).) --we just call this function a swap
((flip.).) :: (a -> a1 -> a2 -> b -> c) -> a -> a1 -> b -> a2 -> c
Prelude> :t (((flip.).).) --we just call this function a swap
(((flip.).).)
:: (a -> a1 -> a2 -> a3 -> b -> c) -> a -> a1 -> a2 -> b -> a3 -> c
और हम पाते हैं कि के साथ और अधिक फ्लिप करने के लिए लागू है, यह मापदंडों के मनमाने ढंग से सटे जोड़ी स्वैप कर सकते हैं (।)। और इसके बाद के संस्करण परिणामों के साथ हम लिख सकते हैं:
Prelude> :t flip
flip :: (a -> b -> c) -> b -> a -> c
Prelude> :t (flip.) . flip
(flip.) . flip :: (a1 -> a -> b -> c) -> a -> b -> a1 -> c
Prelude> :t ((flip.).) . (flip.) . flip
((flip.).) . (flip.) . flip
:: (a2 -> a -> a1 -> b -> c) -> a -> a1 -> b -> a2 -> c
Prelude> :t (((flip.).).) . ((flip.).) . (flip.) . flip
(((flip.).).) . ((flip.).) . (flip.) . flip
:: (a3 -> a -> a1 -> a2 -> b -> c) -> a -> a1 -> a2 -> b -> a3 -> c
हम पा सकते हैं कि और अधिक स्वैप के साथ बना है, यह अंतिम स्थान पर एक मनमाना पैरामीटर खींच सकते हैं। तो हम कई मामलों में लैम्ब्डा अभिव्यक्ति से छुटकारा पा सकते हैं। लेकिन उपर्युक्त एक्सप्रेस बहुत फूला हुआ है।
मेरा मुख्य विचार उपर्युक्त कार्यों को सामान्यीकृत करने के लिए pull
फ़ंक्शन बनाना है। pull
लगभग मोटे तौर पर कार्य करता है।
let f = undefined --For convenience, we let f be undefined.
:t pull 0 (f::a->b->z) --the type variable z is not a function type.
>pull 0 (f::a->b->z) :: b->a->z --pull is just like flip for 0 and a function of this type.
:t pull 0 (f::a->b->c->z) --the type variable z is not a function type.
>pull 0 (f::a->b->c->z) :: b->c->a->z
:t pull 1 (f::a->b->c->z) --the type variable z is not a function type.
>pull 1 (f::a->b->c->z) :: a->c->b->z
:t pull 1 (f::a->b->c->d->z) --the type variable z is not a function type.
>pull 1 (f::a->b->c->d->z) :: a->c->d->b->z
:t pull 2 (f::a->b->c->d->z) --the type variable z is not a function type.
>pull 2 (f::a->b->c->d->z) :: a->b->d->c->z
:t pull 2 (f::a->b->c->d->e->z) --the type variable z is not a function type.
>pull 2 (f::a->b->c->d->e->z) :: a->b->d->e->c->z
मैंने ऐसा करने के कई तरीकों की कोशिश की। naivest एक है:
swap :: Word -> a -> a
swap 0 = flip
swap n = dot $ swap (n-1)
और GHC bellow तरह शिकायत की और मुझे समझ में क्यों:
-- Prelude> :reload
-- [1 of 1] Compiling Main (ModifyArbitrayParameterOfAFunction.hs, interpreted)
--
-- ModifyArbitrayParameterOfAFunction.hs:4:21:
-- Occurs check: cannot construct the infinite type: c0 = a1 -> c0
-- Expected type: (a1 -> c0) -> c0
-- Actual type: (a1 -> c0) -> a1 -> c0
-- In the return type of a call of `modify'
-- Probable cause: `modify' is applied to too few arguments
-- In the first argument of `(.)', namely `(modify (n - 1) modi)'
-- In the expression: (modify (n - 1) modi) . f1
--
-- ModifyArbitrayParameterOfAFunction.hs:4:42:
-- Occurs check: cannot construct the infinite type: c0 = a1 -> c0
-- Expected type: a1 -> a1 -> c0
-- Actual type: a1 -> c0
-- In the second argument of `(.)', namely `f1'
-- In the expression: (modify (n - 1) modi) . f1
-- In an equation for `modify':
-- modify n modi f1 = (modify (n - 1) modi) . f1
-- Failed, modules loaded: none.
हो सकता है कि मेरा लक्ष्य सिर्फ एक इच्छाधारी सोच है, लेकिन हास्केल के प्रकार प्रणाली पर विचार भी लैम्ब्डा भाव लिखने में सक्षम है , मुझे यह कहने की हिम्मत है कि ऐसा करने का एक तरीका होना चाहिए।
मुझे लगता है कि यह संभव है, लेकिन निश्चित रूप से कुछ हल्के ओलेगरी की आवश्यकता होगी। – Artyom
आपके द्वारा वर्णित तरीके से संभव नहीं है। बस क्योंकि रनटाइम पर खींचने के लिए पैरामीटर मान (जो उपलब्ध है) पुल के प्रकार का निर्धारण नहीं कर सकता है (जो संकलन समय पर आवश्यक है) – Ankur
लेकिन, मुझे लगता है कि पुल पैरामीटर फ़ंक्शन पर उचित प्रकार का आधार चुन सकता है, केवल तभी पैरामीटर फ़ंक्शन की पहचान करने का एक तरीका एक यूनरी फ़ंक्शन है, दो चर के फ़ंक्शन या कई चर के फ़ंक्शन – TorosFanny