Kodowałem przy pomocy pakietu soczewek. Wszystko szło dobrze, dopóki nie próbował uzyskać dostęp do jakiegoś pola na typ algebraicznych:Pakiet obiektywów z typami algebraicznymi
import Control.Lens
data Type = A { _a :: Char } | B
makeLenses ''Type
test1 = _a (A 'a')
test2 = (A 'a') ^. a
No instance for (Data.Monoid.Monoid Char)
arising from a use of `a'
Possible fix:
add an instance declaration for (Data.Monoid.Monoid Char)
In the second argument of `(^.)', namely `a'
In the expression: (A 'a') ^. a
In an equation for `test2': test2 = (A 'a') ^. a
może po prostu iść z _a, ale typ danych w moim prawdziwym programem jest znacznie głębszy i rodzaju przeznaczone na użyciu obiektywu zmniejszyć ilość pracy, którą muszę wykonać. Przeglądam bibliotekę obiektywów, ale jest ich tak wiele i nie jestem pewien, czy ma do czynienia z tym scenariuszem, czy jest to po prostu coś, czego biblioteka obiektywów nie obsługuje.
Na marginesie, jeśli faktycznie używam monoidu takiego jak String dla typu danych zamiast Char, to kompiluje i daje właściwą odpowiedź, nie mam pojęcia dlaczego.
Edycja: Po przeczytaniu komentarza hammar za, próbowałem to i to działa:
test2 = (A 'a') ^? a
test3 = B ^? a
Ale to jest trochę dziwne, aby uzyskać może się z tego czegoś, co ma istnieć.
Niezbyt dobrze zna wewnętrzne działanie pakietu soczewek, ale: Zastanów się, co "B ^. a' powinien powrócić. Musi wybrać coś, więc próbuje użyć 'mempty' jako domyślnego zamiast wyrzucania wyjątku takiego jak' _a B'. – hammar
Nie miałem pojęcia, że _ b skompiluje. Miałem błąd w moim kodzie, że nie zdawałbym sobie sprawy, że był tam do czasu uruchomienia i nie było żadnego ostrzeżenia o tym nawet przy Wall. Więc, sądzę, że użyję ^? i być może funkcja i to dokładnie to, czego potrzebuję. –
Właściwie po namyśle doszedłem do wniosku, że metody dostępu do typów algebraicznych to po prostu zły pomysł. Jestem zaskoczony, że jest to dozwolone. Miałem wiele błędów w moim programie, które właśnie wyczyściłem. –