this article on writing polyvariadic functions in Haskell पढ़ने के बाद, मैंने अपना कुछ लिखने की कोशिश की।हास्केल में पॉलीवायरैडिक फ़ंक्शन
पहले मैंने सोचा कि मैं इसे सामान्यीकृत करने का प्रयास करूंगा - इसलिए मेरे पास एक ऐसा कार्य हो सकता है जो दिए गए तर्कों को ध्वस्त करके विविध कार्य करता है।
{-# OPTIONS -fglasgow-exts #-}
module Collapse where
class Collapse a r | r -> a where
collapse :: (a -> a -> a) -> a -> r
instance Collapse a a where
collapse _ = id
instance (Collapse a r) => Collapse a (a -> r) where
collapse f a a' = collapse f (f a a')
हालांकि, संकलक कि पसंद नहीं आया:
Collapse.hs:5:9:
Functional dependencies conflict between instance declarations:
instance Collapse a a -- Defined at Collapse.hs:5:9-20
instance (Collapse a r) => Collapse a (a -> r)
-- Defined at Collapse.hs:7:9-43
अगर मैं वापस चला गया और अंतिम परिणाम के लिए एक आवरण प्रकार जोड़ा, तथापि, यह काम किया:
module Collapse where
class Collapse a r | r -> a where
collapse :: (a -> a -> a) -> a -> r
data C a = C a
instance Collapse a (C a) where
collapse _ = C . id
instance (Collapse a r) => Collapse a (a -> r) where
collapse f a a' = collapse f (f a a')
sum :: (Num a, Collapse a r) => a -> r
sum = collapse (+)
एक बार मैंने यह परिवर्तन करने के बाद, यह ठीक संकलित किया, और ghci
में collapse
फ़ंक्शन का उपयोग कर सकता था।
ghci> let C s = Collapse.sum 1 2 3 in s
6
मुझे यकीन नहीं है कि अंतिम परिणाम के लिए रैपर प्रकार की आवश्यकता क्यों है। अगर कोई इसे समझा सकता है, तो मैं इसकी सराहना करता हूं। मैं देख सकता हूं कि संकलक मुझे बता रहा है कि यह कार्यात्मक निर्भरताओं के साथ कुछ मुद्दा है, लेकिन मैं वास्तव में अभी तक धनपोतों का उचित उपयोग नहीं करता हूं।
बाद में, मैंने एक अलग टक लेने की कोशिश की, और एक सूची लेने वाले कार्यों के लिए एक वैरैडिक फ़ंक्शन जेनरेटर को आजमाएं और परिभाषित करें और एक मान वापस कर दिया। मुझे एक ही कंटेनर चाल करना था, और UndecidableInstances
भी अनुमति देना था।
{-# OPTIONS -fglasgow-exts #-}
{-# LANGUAGE UndecidableInstances #-}
module Variadic where
class Variadic a b r | r -> a, r -> b where
variadic :: ([a] -> b) -> r
data V a = V a
instance Variadic a b (V b) where
variadic f = V $ f []
instance (Variadic a b r) => Variadic a b (a -> r) where
variadic f a = variadic (f . (a:))
list :: Variadic a [a] r => r
list = variadic . id
foldl :: (Variadic b a r) => (a -> b -> a) -> a -> r
foldl f a = variadic (Prelude.foldl f a)
UndecidableInstances
की अनुमति के बिना संकलक शिकायत की कि मेरी उदाहरण घोषणाओं अवैध थे:
ghci> let V l = Variadic.list 1 2 3 in l
[1,2,3]
ghci> let vall p = Variadic.foldl (\b a -> b && (p a)) True
ghci> :t vall
vall :: (Variadic b Bool r) => (b -> Bool) -> r
ghci> let V b = vall (>0) 1 2 3 in b
True
मुझे लगता है:
Variadic.hs:7:0:
Illegal instance declaration for `Variadic a b (V b)'
(the Coverage Condition fails for one of the functional dependencies;
Use -XUndecidableInstances to permit this)
In the instance declaration for `Variadic a b (V b)'
Variadic.hs:9:0:
Illegal instance declaration for `Variadic a b (a -> r)'
(the Coverage Condition fails for one of the functional dependencies;
Use -XUndecidableInstances to permit this)
In the instance declaration for `Variadic a b (a -> r)'
हालांकि, एक बार यह संकलित, मैं इसे सफलतापूर्वक GHCi में इस्तेमाल कर सकते हैं जो मैं खोज रहा हूं वह एक स्पष्टीकरण है कि अंतिम मूल्य के लिए कंटेनर प्रकार क्यों आवश्यक है, साथ ही साथ सभी विभिन्न Functio नल निर्भरता आवश्यक हैं।
इसके अलावा, इस अजीब लग रहा था:
ghci> let vsum = Variadic.foldl (+) 0
<interactive>:1:10:
Ambiguous type variables `a', `r' in the constraint:
`Variadic a a r'
arising from a use of `Variadic.foldl' at <interactive>:1:10-29
Probable fix: add a type signature that fixes these type variable(s)
<interactive>:1:10:
Ambiguous type variable `a'in the constraint:
`Num a' arising from the literal `0' at <interactive>:1:29
Probable fix: add a type signature that fixes these type variable(s)
ghci> let vsum' = Variadic.foldl (+)
ghci> :t vsum'
(Num a, Variadic a a r) => t -> a -> r
ghci> :t vsum' 0
(Num a, Variadic a a r) => a -> r
ghci> let V s = vsum' 0 1 2 3 in s
6
मुझे लगता है कि नतीजों है अनुमान लगा रहा हूँ UndecidableInstances
अनुमति देने से है, लेकिन मैं नहीं जानता कि, और मैं बेहतर समझने के लिए क्या हो रहा है करना चाहते हैं।
यह कुछ बहुत ही अच्छा कोड है जिसके साथ आप प्रयोग कर रहे हैं! और ओलेग Kiselyov द्वारा यह लेख बहुत अच्छा है, यह पहली बार मुझे इसे पढ़ने के लिए पूरी तरह से उड़ा दिया और अभी भी उस प्रभाव है। :-) मैंने रैपर प्रकार की आवश्यकता के संबंध में एक उत्तर में एक शॉट लिया ... उम्मीद है कि यह मदद करता है। –