Chcę zaimplementować Type Class
za pomocą kilku domyślnych metod, ale pojawia się błąd, że nie można używać definicji record selectors
w definicjach type classes
.Selektory rekordów w klasach klasy Haskella
Poniższy kod zasadzie tworzy type class
który definiuje add
funkcję, do której należy dodać element do rekordu jakiegoś data type
repr
. Oto kod:
import qualified Data.Graph.Inductive as DG
class Graph gr a b where
empty :: DG.Gr a b
empty = DG.empty
repr :: gr -> DG.Gr a b
-- following function declaration does NOT work:
add :: a -> gr -> gr
add el g = g{repr = DG.insNode el $ repr g}
kompilator zgłasza błąd:
repr is not a record selector
In the expression: g {repr = DG.insNode el $ repr g}
In an equation for add:
add el g = g {repr = DG.insNode el $ repr g}
Czy jest możliwe aby zadeklarować takich metod w Haskell?
Wyjaśnienie
muszę taką konstrukcję, bo mam trochę data types
, które zachowują się w sposób simmilar. Powiedzmy, że mamy A
, B
i C
data types
. Każdy z nich powinien mieć rekord repr :: DG.Gr a b
, gdzie a
i b
są odrębne dla każdego z A
, B
i C
.
A
, B
i C
te same funkcje, jak add
lub delete
(która w zasadzie dodać lub usunąć elementy nagrać repr
). Jeśli te typy danych mają wiele funkcji, ma to sens, aby zaimplementować funkcje w type class
i utworzyć wystąpienia tego type class
- te funkcje zostaną automatycznie zaimplementowane dla każdego z naszych data type
.
Dodatkowe Chciałbym niektóre z tych data types
(powiedzmy, że chcę B
) zachowywać się nieco inaczej, wywołując funkcję add
na nim. Łatwo jest zaimplementować to zachowanie podczas tworzenia instance
z dla dla dla dla.
Odpowiedź brzmi „nie”, ale "w pewnym sensie, używając soczewek", ale co ważniejsze, czuję, że istnieje fundamentalne nieporozumienie dotyczące tego, jakie klasy są tutaj. Pomogłoby to bardzo, gdybyś powiedział, że chcesz mieć taką klasę; możemy zaproponować bardziej idiomatyczną alternatywę. –
@DanielWagner - Dodałem wyjaśnienie problemu, który próbuję rozwiązać - mam nadzieję, że teraz jest jasne, dlaczego próbuję to zrobić :) –
Wyświetl moją zaktualizowaną odpowiedź. W drugim przykładzie używam metody 'update', która wykonuje aktualną aktualizację (może być zaimplementowana za pomocą tej składni aktualizacji rekordów w instancjach), a trzeci przykład używa' Control.Lens'. – JJJ