api List vs Półgrupa i Funktor

api List vs Półgrupa i Funktor
KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5550
1

Cześć
Dręczy mnie taki problem:
W Haskellu Listy mają swoje własne dedykowane api jak operator ++ i funkcja map. Istnieją też dla listy implementacje typeclass Semigroup i Functor. Semigroup dostarcza operator <> który robi dokładnie to samo co operator ++, a Functor dostarcza funkcję fmap, która robi dokładnie to samo co funkcja map.
Są może jakieś zalecenia i dobre praktyki dla Haskella którego api należy używać? Czy tego dedykowanego dla list czy tego ogólnego które można zaimplementować dla wszystkich typów danych?

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
3

Są może jakieś zalecenia i dobre praktyki dla Haskella którego api należy używać?

Popatrzyłbym na jakieś popularne aplikacje i biblioteki Haskellowe (pomijając bibliotekę standardową).

Czy tego dedykowanego dla list czy tego ogólnego które można zaimplementować dla wszystkich typów danych?

Ja bym to rozgraniczył ten sposób:

  • Jeśli używam kolekcji i tylko kolekcja ma sens w danym miejscu, a nie dowolny funktor czy monada to używam API idiomatycznego dla kolekcji.
  • Jeśli używam jakiegoś typu, który może być kolekcją, ale kod ma sens i potencjalnie jest przydatny dla wielu typów nie będących kolekcjami to używam API z typeclass. Jednocześnie warto zmienić kod tak by przyjmował ten funktor czy monadę, a nie konkretnie kolekcję i wtedy wiadomo po co nastąpiła zmiana użytych operatorów.
PA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 426
2

Wszystko zależy od tego jak generyczny ma być twój kod. Jeżeli twoja funkcja ma obsługiwać tylko stringa, to najprościej dać ++. mappend albo <> pozwoli Ci na pisanie bardziej generycznych funkcji.

Pamiętaj, że Funktor to bardzo ogólna abstrakcja i jeżeli napiszesz funkcję, która na niej operuję, to będziesz mógł do niej przekazywać nawet inne funkcje.

Kopiuj
foo = fmap (+ 2)

bar = foo (+ 4)

main = print $ bar 5

Jeżeli twoja funkcja ma być aż tak generyczna, to nie widzę problemu, żeby używać ogólnych abstrakcji. Problem w tym, że taka lista jest instancją wielu klas i to

Kopiuj
foo :: [Integer] -> Integer
foo = foldr (-) 0 . fmap (+ 2)

jest jednak czytelniejsze od tego

Kopiuj
bar :: (Foldable m, Functor m, Num a) => m a -> a
bar = foldr (-) 0 . fmap (+ 2)
KamilAdam
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Silesia/Marki
  • Postów: 5550
0

Są może jakieś zalecenia i dobre praktyki dla Haskella którego api należy używać?

Znalazłem kowainik:

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.