2015-06-30 19 views
6

Próbując zapoznać się z doskonałymi pomysłami, takimi jak Foldable, Functor itp., Piszę strukturę danych dla matrycy 2 * 2. To nie jest dla rzeczywistego użytkowania, więc myślałem, że to naiwne realizacja jest dobry początek:Klasa "Zippable" dla haskell?

data Matrix2d a = M2 a a a a 

chcę to być Num instancję

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) 
    -- .... 

nie wydaje się słuszne. Nie chcę wpisywać pięciokrotnie numeru + dla tej oczywistej definicji. Na pewno jest miejsce na więcej abstrakcji. Wolałbym coś takiego

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

To jest rzeczywiście łatwe do wdrożenia:

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) 

jednak nie mogłem nic znaleźć gotowy do użycia w hoogle. Uważam to za dziwne, ponieważ ten rodzaj abstrakcji wydaje się całkiem naturalny. Jest Foldable, jest Functor --- dlaczego nie Zippable?

Pytania:

  • Czy istnieje moduł, który zapewnia tę funkcję?
  • Jeśli nie (wydaje mi się, że tak jest), jakie mam opcje? Czy definiowanie własnej klasy jest najlepszym wyborem, czy jest jakaś lepsza alternatywa?
+1

Zapoznaj się z haskell: http://learnyouahaskell.com/funkcje-plikatywne -funkcje-andmonoidy – AJFarmar

+2

To nie jest super praktyczna odpowiedź, ale [F-algebras] (https: //lukepalmer.wordpress. com/2013/03/12/constructions-on-typeclasses-part-1-f-algebras /) zapewniają bardzo regularną strukturę do uzyskiwania funkcji takich jak '(+)' za darmo. – luqui

Odpowiedz

6

Nie można zrobić wiele z tylko Functor, ale z Applicative można zrobić

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

Domyślna instancja dla Applicative [] nie zrobi zupełnie co chcesz; To zajmie coa z co. Ale uważam, że istnieje nowy typ ZipList, który daje instancję zamieniającą się w oczekiwany sposób. (Nie, nie wiem dokładnie, gdzie mieszka.)

Zauważ, że to uogólnienia do żadnego liczbę argumentów:

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

więc nie potrzebują zipWith, zipWith3, zipWith4, funkcje dodatkowe.

+0

Czy możesz dodać przykład implementacji? Napisałem [to] (https://gist.github.com/anonymous/417585e7f6d54ddfc7fd) według twojej sugestii, czy to wszystko w porządku? – Yosh

+0

@ Yosh Twoja implementacja wygląda mi dobrze. – MathematicalOrchid

+1

[Domyślnie] (https://github.com/agda/agda-stdlib/blob/master/src/Data/Vec.agda#L69) Instancja "Applicative" dla wektorów koduje skompresowanie. Tłumaczenie na Haskella jest proste. – user3237465

Powiązane problemy