मैं एक ढांचा लिख रहा हूं, जहां मुख्य कार्य उपयोगकर्ता को a -> [b]
के प्रकार के बारे में पूछता है।क्या रीडर के समानता और सामान्य कार्य का उपयोग करने के लिए कोई "मानक" तरीका है?
हालांकि, क्योंकि है कि समारोह काफी जटिल हो सकता है, इसके कार्यान्वयन अक्सर इस तरह दिख सकता:
fn a = extractPartOfAAndConvert a ++ extractAnotherPartofAAndConvert a
इसलिए मैं Reader
कि लड़ने के लिए एक अच्छा, मुहावरेदार विचार का उपयोग कर सकते लगा। हालांकि, साथ ही मुझे एहसास हुआ कि कुछ लोग एक मोनड का उपयोग नहीं करना चाहते हैं।
प्रयोग करते हैं, मैं इस समाधान से तैयार किया है:
class Iso a b where
isoFrom :: a -> b
isoTo :: b -> a
instance Iso a a where
isoFrom = id
isoTo = id
instance Iso (a -> b) (Reader a b) where
isoFrom f = reader f
isoTo m = runReader m
कौन सा बदले में मुझे क्या करना अनुमति देता है:
testCallback :: MyState -> Callback -> MyState
testCallback myState cb = cb myState
-- The important signature
testCallbackGeneric :: Iso Callback a => MyState -> a -> MyState
testCallbackGeneric myState cb = (isoTo cb) myState
callbackFunction :: Callback
callbackFunction s = s + 10
callbackMonad :: Reader MyState MyState
callbackMonad = do
x <- ask
return $ x - 10
-----------
let myStateA = testCallback myState callbackFunction
-- let myStateB = testCallback myState callbackMonad -- won't work, obviously
let myStateC = testCallbackGeneric myState callbackFunction
let myStateD = testCallbackGeneric myState callbackMonad
हालांकि, मुझे लगता है कि बहुत ज्यादा है कि मैं पहिया पुनर्रचना कर रहा हूँ।
क्या रीडर के समतुल्य को व्यक्त करने का कोई तरीका है कि इस तरह के सामान्य कार्यों को आसानी से लिखने के बिना अपना खुद का प्रकार वर्ग बनाने के लिए?
एक और बात है कि क्या यह इस तरह के व्यापक हस्ताक्षर, जहां उपयोगकर्ता केवल preferrable में बदल सकते हैं प्रदान करने के लिए वास्तव में worthwile है रास्ता, बस उदाहरण की तरह करता है। मुझे लगता है कि ऐसा कोई कारण नहीं है कि बॉयलरप्लेट को उपयोगकर्ता से बचाया/नहीं लिया जाना चाहिए। –
आप 'मोनाड रीडर' बाधा का उपयोग कर सकते हैं, जिसके लिए फ़ंक्शंस के लिए पहले से मौजूद एक उदाहरण मौजूद है। यदि आप 'f = do {a <- पूछते हैं; $ 2 * ए + 3 * ए} वापस करें, फिर आप इसे 'एफ 1 == 5' या किसी भी' रीडर 'फ़ंक्शन में' f :: MonadReader Int m => m Int' के रूप में फ़ंक्शन के रूप में उपयोग कर सकते हैं। यह 'Int -> Int' या' Reader Int Int 'के लिए विशेषज्ञ हो सकता है। – bheklilr
@bheklilr * जिसके लिए पहले से ही कार्यों के लिए एक उदाहरण मौजूद है। * यह। यही वह था जो मैं पूरे समय लापता था! इसे एक उत्तर के रूप में लिखें ताकि मैं इसे ऊपर उठा सकूं! :) (और हाँ 'कॉलबैक' सिर्फ 'मायस्टेट -> माइस्टेट', और' मायस्टेट ~ Int') –