2015-06-30 6 views
6

Foldable, Functor आदि जैसे महान विचारों से परिचित होने के प्रयास में, मैं 2 * 2 मैट्रिक्स के लिए डेटा संरचना लिख ​​रहा हूं। यह असली इस्तेमाल के लिए नहीं है, तो मुझे लगा कि यह अनुभवहीन कार्यान्वयन एक अच्छी शुरुआत है:हैकेल के लिए "ज़िप्पेबल" कक्षा?

data Matrix2d a = M2 a a a a 

मैं इस एक Num उदाहरण

instance Num a => Num (Matrix2d a) where 
    (M2 a0 b0 c0 d0) + (M2 a1 b1 c1 d1) = M2 (a0+a1) (b0+b1) (c0+c1) (d0+d1) 
    -- .... 

यह सही नहीं लगता है होना चाहता हूँ। मैं इस स्पष्ट परिभाषा के लिए पांच बार + टाइप नहीं करना चाहता हूं। निश्चित रूप से अधिक अमूर्तता के लिए जगह है। मैं की तरह

(+) = fzipWith (+) -- f does not mean anything here 

कुछ पसंद करते हैं यह वास्तव में लागू करने के लिए आसान है:

class Zippable z where 
    fzipWith :: (a -> b -> c) -> z a -> z b -> z c 

instance Zippable Matrix2 where 
    fzipWith f (M2 x y z w) (M2 a b c d) = M2 (f x a) (f y b) (f z c) (f w d) 

हालांकि, मैं कुछ भी नहीं मिला रेडी-टू-उपयोग hoogle में। मुझे यह अजीब लगता है क्योंकि इस तरह का अमूर्तता काफी प्राकृतिक लगता है। Foldable है, Functor है --- Zippable क्यों नहीं?

सवाल:

  • वहाँ किसी भी मॉड्यूल है कि इस सुविधा प्रदान करता है है?
  • यदि नहीं (मुझे विश्वास है कि यह मामला है), मेरे पास कौन से विकल्प हैं? मेरी अपनी कक्षा को सबसे अच्छा विकल्प परिभाषित कर रहा है, या क्या कोई बेहतर विकल्प है?
+1

आपको एक हैकेल सीखें: http://learnyouahaskell.com/functors-plplative-functors-and-monoids – AJFarmar

+2

यह एक सुपर व्यावहारिक उत्तर नहीं है, लेकिन [एफ-बीजगणित] (https: //lukepalmer.wordpress। कॉम/2013/03/12/निर्माण-ऑन-टाइपक्लास-भाग -1-एफ-बीजगणित /) मुफ्त में '(+)' जैसे कार्यों को प्राप्त करने के लिए एक बहुत ही नियमित संरचना प्रदान करते हैं। – luqui

उत्तर

6

तुम बस Functor साथ ज्यादा कुछ नहीं कर सकते हैं, लेकिन Applicative साथ आप

fzipWith f za zb = f <$> za <*> zb 

Applicative [] के लिए डिफ़ॉल्ट उदाहरण से काम नहीं चलेगा काफी आप क्या चाहते हैं कर सकते हैं; प्रत्येकaप्रत्येकb के साथ ले जाएगा। लेकिन मेरा मानना ​​है कि ZipList न्यूटाइप कहीं है जो आपको एक उदाहरण देता है जिसकी आप उम्मीद कर रहे हैं। (नहीं, मैं वास्तव में नहीं जानता कि जहां यह रहता है।)

ध्यान दें कि यह को generalises तर्कों में से किसी संख्या:

f <$> za <*> zb <*> zc <*> zd 

ताकि आप की जरूरत नहीं है zipWith, zipWith3, zipWith4, आदि कार्यों।

+0

क्या आप कार्यान्वयन का एक उदाहरण जोड़ सकते हैं? मैंने आपके सुझाव के अनुसार [यह] (https://gist.github.com/anonymous/417585e7f6d54ddfc7fd) लिखा है, क्या यह ठीक है? – Yosh

+0

@Yosh आपका कार्यान्वयन मेरे लिए अच्छा लग रहा है। – MathematicalOrchid

+1

[डिफ़ॉल्ट] (https://github.com/agda/agda-stdlib/blob/master/src/Data/Vec.agda#L69) वैक्टर एन्कोड्स ज़िप के लिए 'आवेदक' उदाहरण। हास्केल का अनुवाद सरल है। – user3237465

2

अनुलग्नक पैकेज देखें, और विशेष रूप से Data.Functor.Rep.liftR2 देखें।

आपका Matrix2 एक प्रतिनिधित्व करने योग्य मज़ेदार है।