मैं वर्तमान में प्रतिक्रियाशील केले के साथ एफआरपी सीख रहा हूं और यादृच्छिक कार्यों की एक धारा बनाना चाहता था।पॉलिमॉर्फिक कार्यों की एक ईवेंट स्ट्रीम बनाएं - संभव है? यदि हां, तो कैसे?
-- | take number generator, and some pulse event stream, generate random function stream
mkRandom :: (Random a,RandomGen g) => g -> Event t b -> Event t ((a,a) -> a)
mkRandom rng es = (\f -> \r -> fst $ f r) <$> (accumE first $ next <$> es)
where first = flip randomR rng
next _ prev range = randomR range g
where (a,g) = prev range
ऐसा लगता है काम करने के लिए, मैं इस तरह इसका इस्तेमाल कर सकते हैं:: मैं इस के साथ आ गया है,
randFuncs = mkRandom rnd (pulse 1000 time)
some = ($ (0,10::Int)) <$> randFuncs
लेकिन निश्चित रूप से, जब मुझे लगता है कि धारा की संख्या उत्पन्न करने के लिए साझा करने का प्रयास एक अलग प्रकार:
some2 = ($ (0,10::Double)) <$> randFuncs
टाइप चेकर शिकायत करता है, जो मैं समझता हूं। तब मैं निम्नलिखित करने के लिए समारोह सामान्यीकरण करने की कोशिश की:
mkRandom :: (RandomGen g) => g -> Event t b -> Event t (forall a. Random a => (a,a) -> a)
फिर GHC अवैध बहुरूपी हस्ताक्षर के बारे में शिकायत और है कि क्या मैं ImpredicativeTypes सक्षम करना चाहते हैं। मैंने ऐसा किया और काफी समय से इसे काम करने के लिए सब कुछ एनोटेट करने की कोशिश की, लेकिन जीएचसी ने हमेशा शिकायत की कि यह प्रकारों से मेल नहीं खा सकता है।
मेरा सवाल है - क्या मैं चाहता हूं कि यह करना संभव हो? क्या मुझे वास्तव में इसके लिए अपरिवर्तनीय प्रकार की आवश्यकता है या क्या मैं इसे गलत कर रहा हूं?
मैंने सोचा कि रैंकेंटाइप्स इसके लिए पर्याप्त होना चाहिए, लेकिन मुझे अभी तक ऐसे एक्सटेंशन के साथ कोई अनुभव नहीं है।
अग्रिम धन्यवाद!
संपादित करें:
रिकॉर्ड के लिए, अब उपयोगी प्रतिक्रिया के आधार पर मेरे समाधान है:
newtype RandomSource = Rand { getRand :: forall a. (Random a) => (a,a) -> [a] }
-- | take number generator and some pulse event stream, generate randomness stream
mkRandom :: RandomGen g => g -> Event t a -> Behavior t RandomSource
mkRandom rng es = fst <$> (accumB (next id (id,rng)) $ next <$> es)
where next _ (_,rng) = (Rand $ flip randomRs g1, g2)
where (g1,g2) = split rng
-- | take a rand. source, a range and a pulse, return stream of infinite lists of random numbers
randStream :: Random a => Behavior t RandomSource -> (a,a) -> Event t b -> Event t [a]
randStream funcs range pulse = ($ range) . getRand <$> funcs <@ pulse
मुझे बताया गया है कि प्रतिक्रियाशील-केले 1.0 (वर्तमान 'मास्टर') गैर-तुच्छ और पर्याप्त तरीकों से प्रकारों को सरल बना देगा, जैसे 'रैंकेंटीप्स' (कुछ परिदृश्यों में) की आवश्यकता नहीं है, तो आप इसे दे सकते हैं प्रयत्न। –
@ErikAllik एपीआई प्रतिक्रियाशील-केला 1 के लिए बदलता है।0 मुख्य रूप से प्रकार पैरामीटर 'टी' चिंता करते हैं। हाथ में सवाल इस से असंबंधित है। –