एक प्रकार-hackery अभ्यास के रूप में प्राप्त करने के लिए यह मानक सूचियों के साथ इस लागू करने के लिए संभव है।
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts,
UndecidableInstances, IncoherentInstances,
TypeFamilies, ScopedTypeVariables #-}
import Data.List
import Data.Function
class StringGroupable a b where
groupStringBy :: Pred -> a -> b
instance (StringGroupable a b, r ~ [b]) => StringGroupable [a] r where
groupStringBy f = map (groupStringBy f)
instance (r ~ [[String]]) => StringGroupable [String] r where
groupStringBy p = groupBy p
कौन इस तरह काम करता है::
*Main> let lst = ["11","11","22","1","2"]
*Main> groupStringBy ((==) `on` length) lst
[["11","11","22"],["1","2"]]
*Main> groupStringBy (==) . groupStringBy ((==) `on` length) $ lst
[[["11","11"],["22"]],[["1"],["2"]]]
तो हम सीधे हालांकि यह उलटे क्रम में डाल दिया जाना है इस सुविधा का उपयोग कर सकते हैं (
हम सभी की जरूरत है एक मनमाना गहराई groupStringsBy समारोह है):
inp = ["1.1", "1.2.1", "1.2.2", "2.1", "2.2", "3"]
deweyGroup :: Int -> String -> String -> Bool
deweyGroup i a b = a!!idx == b!!idx where idx = 2*(i-1)
-- gives: [[["1.1"],["1.2.1","1.2.2"]],[["2.1"],["2.2"]],[["3"]]]
test1 = groupStringBy (deweyGroup 2) . groupStringBy (deweyGroup 1) $ inp
लेकिन यदि आप अपने मूल नमूना का उपयोग करना चाहते हैं, तो हम इसे भी हैक कर सकते हैं।
class App a b c r where
app :: (a -> b) -> c -> r
instance (b ~ c, App a d n r1, r ~ (n -> r1)) => App a b (c -> d) r where
app c f = \n -> app (f . c) n
instance (a ~ c, r ~ b) => App a b c r where
app c a = c a
निर्माण इस तरह::
*Main> app not not not True
False
*Main> app (+3) (*2) 2
10
पहले हम एक चर तर्क समारोह जो पाइपलाइनों सभी तर्कों लेकिन
.
के माध्यम से उलटे क्रम में पिछले एक है और फिर अंतिम तर्क पर लागू होता है, जिसके परिणामस्वरूप समारोह की जरूरत है
type Pred = String -> String -> Bool
instance (StringGroupable b c, App a c n r1, r ~ (n -> r1)) => App a b Pred r where
app c p = app ((groupStringBy p :: b -> c) . c)
और अंत में w:
तो हमारे विधेय प्रकार type Pred = String -> String -> Bool
के लिए कोई कस्टम नियम के साथ विस्तार rGroupBy
में यह रैप (आपूर्ति id
समारोह पाइप लाइन में प्रथम माना जाता है):
rGroupBy :: (App [String] [String] Pred r) => Pred -> r
rGroupBy p = app (id :: [String] -> [String]) p
अब यह आपूर्ति की विधेय की संख्या के बराबर गहराई की सूची का निर्माण प्रकार Pred
की विधेय समूहीकरण के किसी भी संख्या के लिए काम करना चाहिए :
-- gives: [["1.1","1.2.1","1.2.2"],["2.1","2.2"],["3"]]
test2 = rGroupBy (deweyGroup 1) inp
-- gives: [[["1.1"],["1.2.1","1.2.2"]],[["2.1"],["2.2"]],[["3"]]]
test3 = rGroupBy (deweyGroup 1) (deweyGroup 2) inp
-- gives: [[[["1.1"]],[["1.2.1","1.2.2"]]],[[["2.1"]],[["2.2"]]],[[["3"]]]]
test4 = rGroupBy (deweyGroup 1) (deweyGroup 2) (deweyGroup 1) inp
तो यह संभव है (और शायद सरल किया जा सकता है), लेकिन हमेशा की तरह hackery की इस तरह के साथ कुछ भी लेकिन व्यायाम के लिए प्रयोग की जाने वाली अनुशंसित नहीं है।
दिलचस्प सवाल। जब आप कहते हैं "यह आगे नहीं जाना जाता है" क्या आपका मतलब संकलन समय पर है? यदि ऐसा है तो आप भाग्य से बाहर हो सकते हैं, क्योंकि हैकेल स्थिर रूप से टाइप किया गया है। सी/सी ++ में – jberryman
एक सूची आमतौर पर एक सरणी होती है, एक सरणी आमतौर पर 2 आयाम मैट्रिक्स होती है, सरणी की एक सूची बनाने का अर्थ है कि आप 1 से 3 तक आयामों को बढ़ा रहे हैं, सरणी की एक सूची एक 3 डी मैट्रिक्स है (एक अमूर्त दृष्टिकोण से); मुझे हास्केल नहीं पता लेकिन शायद आपकी समस्या सिर्फ मैट्रिक्स/वेक्टर आयामों के बारे में है। – user827992
@ user827992, हास्केल में, एक सूची एक सूची है, एक सरणी नहीं है।(यह एक सिंगल-लिंक्ड सूची है, सटीक होने के लिए) – dflemstr