मैंने numpy के array
के समान फ़ंक्शन बनाया है। यह सरणियों के लिए सूचियों, 2 डी सरणियों के लिए सूचियों की सूची, आदिहास्केल प्रकार परिवार और डमी तर्क
यह इस तरह काम करता है धर्मान्तरित:
ghci> arrFromNestedLists ["hello", "world"] :: Array (Int, (Int,())) Char
array ((0,(0,())),(1,(4,()))) [((0,(0,())),'h'),((0,(1,())),'e'),((0,(2,())),'l'),((0,(3,())),'l'),((0,(4,())),'o'),((1,(0,())),'w'),((1,(1,())),'o'),((1,(2,())),'r'),((1,(3,())),'l'),((1,(4,())),'d')]
(Int, (Int,()))
और नहीं (Int, Int)
क्योंकि मैं की लंबाई बढ़ाने के लिए एक programatic रास्ते से पता नहीं है एक ट्यूपल (साइड सवाल: क्या ऐसा कोई तरीका है?)
इसकी कोडिंग अजीब थी और मुझे काम करने के लिए "वर्कअराउंड" (काम करने के लिए डमी तर्कों के आसपास गुजरना) करना पड़ा। मुझे आश्चर्य है कि क्या एक बेहतर तरीका है।
{-# LANGUAGE FlexibleInstances, ScopedTypeVariables, TypeFamilies #-}
type family ListOfIndex i a
type instance ListOfIndex() a = a
type instance ListOfIndex (Int, i) a = [ListOfIndex i a]
class Ix i => ArrConv i where
acBounds :: a -> ListOfIndex i a -> (i, i)
acFlatten :: i -> ListOfIndex i a -> [a]
acBounds
हो "चाहिए" :: ListOfIndex i a -> (i, i)
:
तो यहाँ कोड, बदसूरत समाधान के विवरण के साथ बाधित है। और इसी तरह acFlatten
के लिए। प्रत्येक एक डमी चर (undefined
हमेशा दिए गए मान है) क्योंकि अन्यथा मैं नहीं मिल सका यह संकलन करने :(
arrFromNestedLists :: forall i a. ArrConv i => ListOfIndex i a -> Array i a
arrFromNestedLists lst =
listArray
(acBounds (undefined :: a) lst)
(acFlatten (undefined :: i) lst)
ऊपर डमी undefined
तर्क काम पर से गुजर रहा है दिया जाता है। यह GHC जिनमें से उदाहरण बताता है ListOfIndex
उपयोग करने के लिए।
instance ArrConv() where
acBounds _ = const ((),())
acFlatten _ = (: [])
नीचे समारोह ArrConv
का एक उदाहरण में acBounds
समारोह किया गया चाहिए है, और बाहर घोषित किया जाता है सिर्फ इसलिए कि मैं ScopedTypeVariables
उपयोग करने की आवश्यकता है और मैं कैसे मैं एक में कर सकते हैं पता नहीं है एक उदाहरण परिभाषा में समारोह ..
acSucBounds
:: forall a i. ArrConv i
=> a -> [ListOfIndex i a] -> ((Int, i), (Int, i))
acSucBounds _ lst =
((0, inStart), (length lst - 1, inEnd))
where
(inStart, inEnd) = acBounds (undefined :: a) (head lst)
instance ArrConv i => ArrConv (Int, i) where
acBounds = acSucBounds
acFlatten _ = concatMap (acFlatten (undefined :: i))
"मुझे टुपल की लंबाई बढ़ाने के लिए प्रोग्रामेटिक तरीके से नहीं पता है।" मुझे नहीं लगता कि आप कर सकते हैं। यह एक फ़ंक्शन का एक आदर्श उदाहरण है जिसका प्रकार किसी मान पर निर्भर करता है। 'एग्डा' जैसी निर्भर रूप से टाइप की गई भाषा में करना आसान होगा, लेकिन हास्केल में असंभव है। हो सकता है कि आप कुछ आश्रित व्यवहार देने के लिए किसी भी तरह से 'जीएडीटीएस' का उपयोग कर सकें, लेकिन मेरे सिर के ऊपर से, मुझे नहीं पता कि कैसे। –
हो सकता है कि टेम्पलेट हास्केल उपयोगी हो: http://www.haskell.org/bz/thdoc.htm http://www.haskell.org/haskellwiki/Template_Haskell – primodemus
@primodemus: TH के साथ मैं 'ArrConv' के लिए उदाहरण बना सकता हूं 10 आयामों के सरणी के लिए, और वे इंडेक्स के लिए सामान्य टुपल्स का उपयोग करेंगे, जो एक सुधार है।लेकिन मुझे लगता है कि सीमा मनमानी है और कोड शायद बहुत कम पठनीय होने जा रहा है। – yairchu