Próbuję zdefiniować typ dla list o stałej długości w Haskell. Kiedy używam standardowego sposobu kodowania liczb naturalnych jako typów w trybie jednoargumentowym, wszystko działa poprawnie. Jednak kiedy próbuję budować wszystko na literałach typu GHC, napotykam mnóstwo problemów.Listy o stałej długości i typie literowym
Mój pierwszy strzał w żądanym typu listy był
data List (n :: Nat) a where
Nil :: List 0 a
(:>) :: a -> List n a -> List (n+1) a
które niestety nie pozwalają na pisanie funkcji zip z rodzaju
zip :: List n a -> List n b -> List n (a,b)
mogę rozwiązać ten problem poprzez odjęcie 1 od typ zmienna n
w typie (:>)
:
data List (n :: Nat) a where
Nil :: List 0 a
(:>) :: a -> List (n-1) a -> List n a -- subtracted 1 from both n's
Następnie próbowałem zdefiniować funkcję append:
append :: List n1 a -> List n2 a -> List (n1 + n2) a
append Nil ys = ys
append (x :> xs) ys = x :> (append xs ys)
Niestety, GHC mówi mi
Couldn't match type ‘(n1 + n2) - 1’ with ‘(n1 - 1) + n2’
Dodanie ograniczenia ((n1 + n2) - 1) ~ ((n1 - 1) + n2)
do podpisu nie rozwiązuje problemów, ponieważ GHC narzeka
Could not deduce ((((n1 - 1) - 1) + n2) ~ (((n1 + n2) - 1) - 1))
from the context (((n1 + n2) - 1) ~ ((n1 - 1) + n2))
Teraz, oczywiście, złapałem jakąś nieskończoną pętlę.
Chciałbym więc wiedzieć, czy możliwe jest zdefiniowanie typu dla list o stałej długości przy użyciu literałów typu w ogóle. Czy mógłbym nawet nadzorować bibliotekę właśnie w tym celu? Zasadniczo jedynym wymaganiem jest to, że chcę napisać coś w stylu List 3 a
zamiast .
można znaleźć dyskusję na temat zagadnień związanych długości wektora w papierze Hasochism na poziomie typu-: https://personal.cis.strath.ac.uk/conor.mcbride/pub/hasochism. pdf – chi
"Hasochizm" brzmi naprawdę kusząco. Dam jednak papierowi szansę. Dziękuję Ci. –
Najprawdopodobniej łatwiejsze jest otworzenie nowego typu na zwykłej liście z dołączonym 'Nat', podobnie jak robi to' Linear.V'. Możesz zdefiniować kilka prymitywów w jednym module i ukryć konstruktor, aby wszystko było bezpieczne. – cchalmers