2012-05-17 6 views
13
data Ray = Ray Vector Vector 

lubHaskell: dane algebraiczne vs krotka

type Ray = (Vector, Vector) 

który jest preferowany w idiomatycznym Haskell? Dlaczego powinienem używać jednego nad drugim?
Nie dbam o wydajność.

Wydaje zrobić małą różnicę z funkcjami, np

trace :: Ray -> … 

trace (Ray x d) = … 
-- OR 
trace (x, d) = … 

Odpowiedz

10

Wersja data jest korzystny, gdyż bardziej wyraźnie wskazuje na intencje programisty - stworzenie nowego typu, jesteś wskazując na wszystko że to nie jest tylko krotka, ale znacząca jednostka semantyczna, Ray.

Dzięki temu możliwe jest dalsze oparcie się na systemie typów, z niestandardowymi instancjami dla Ray, a optymalizacje niemożliwe w krotkach.

+1

Dobrze. I krytyczny punkt dotyczący typów: dotyczą one znacznie więcej niż reprezentacji danych; charakteryzują użyteczną strukturę. – pigworker

+0

OK, to ma sens. "typ" jest tak naprawdę dla synonimu, a nie dla nowego typu danych. Ale linia musi być gdzieś narysowana - odpowiedni kolor = (Int, Int, Int) byłby odpowiedni, prawda? – mk12

+2

Nie, ze względu na wydajność bardziej sensowne jest posiadanie zapakowanego typu wektorowego dla Kolorów, jak w pakiecie kolorystycznym - znaczące rodzaje, takie jak ten, mogą być zoptymalizowane i wyspecjalizowane. http://hackage.haskell.org/packages/archive/colour/2.3.3/doc/html/src/Data-Colour-Internal.html#Colour –

6

Można również rozważyć trzecią opcję, która jest swego rodzaju połączeniem dwóch: newtype

newtype Ray = Ray (Vector, Vector) 

algebraiczne typy danych, moim zdaniem, są stosowane w sytuacjach, gdy masz wiele alternatyw, lub w przypadkach, gdy potrzebujesz typu, aby był rekursywny, zawierający się. Ale może to być przesada dla czegoś takiego.

Don Stewart zwrócił uwagę, że tworzenie synonimów dla krotki jest tym samym, co używanie bezpośrednio tego typu krotki; synonimy typu nie mają własnej tożsamości. Tak więc sprawdzanie typu nie byłoby w stanie odróżnić typu i krotki, więc nie może sprawdzić, czy używasz tego typu, w którym chcesz. Ponadto miałoby to dokładnie takie same przypadki, jak krotka.

A newtype pozwala na użycie tego samego bazowego typu co krotka; ale jest to osobny typ do sprawdzania typu, z osobnymi instancjami.

+0

To wydaje się być mniej powszechne niż przy użyciu curry formularza. Być może tylko dlatego, że jest to więcej interpunkcji. – luqui

3

Czwarty alternatywą znalazłem dość wygodne zapisy:

data Ray = Ray { from, to :: Vector } 

Mają zasadzie wszystkie cechy „normalnych” ADTS, ale z jakiegoś dodatkowego cukru składniowej. W szczególności ułatwiają uzyskanie częściowo zmodyfikowanych kopii wartości. To prawda, że ​​nagrania są zbyt ograniczone w niektórych sytuacjach, ale możesz pójść dalej dzięki "ulepszonym wersjom", takim jak fclabels.