Zippable class for haskell?

In an attempt to get to know great ideas like Foldable , Functor , etc. I am writing a data structure for a 2 * 2 matrix. This is not for real use, so I thought this naive implementation was a good start:

 data Matrix2d a = M2 aaaa 

I want it to be an instance of 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) -- .... 

This does not seem right. I do not want to dial + five times for this obvious definition. Of course, there is room for more abstraction. I would prefer something like

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

It is actually easy to implement:

 class Zippable z where fzipWith :: (a -> b -> c) -> za -> zb -> zc instance Zippable Matrix2 where fzipWith f (M2 xyzw) (M2 abcd) = M2 (fxa) (fyb) (fzc) (fwd) 

however, I could not find anything ready to use on hoogle. I find it strange, because this abstraction seems quite natural. There Foldable , there Functor --- why not Zippable ?

Questions:

  • Is there any module that provides this functionality?
  • If not (I think so), what are my options? Is defining my own class a better choice or is there a better alternative?
+6
source share
2 answers

You cannot do much with Functor , but with Applicative you can do

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

The default instance for Applicative [] will not do what you want; he will take every a with every b . But I believe that somewhere there is a ZipList newtype that gives you an instance that fastens as you expect. (No, I don’t know exactly where he lives.)

Note that this generalizes to any number of arguments:

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

therefore you do not need the functions zipWith , zipWith3 , zipWith4 , etc.

+6
source

See the add-on package, and in particular Data.Functor.Rep.liftR2 .

Your Matrix2 is a representable functor.

+2
source

Source: https://habr.com/ru/post/990026/


All Articles