Wpadłem w dziwną sytuację w GHC 8.0.1 z dobrymi indeksami (?) GADTs, w których wprowadzenie kombinezonów w sygnaturach typu i rodzaju powoduje różne sprawdzanie typów zachowania."Rodzaj" zdezorientowany na temat all-in w GADTs indeksowanych
Rozważmy następujące typy danych:
{-# LANGUAGE TypeInType, GADTs, ExplicitForAll #-}
-- Same thing happens when we replace ExplicitForAll with ScopedTypeVariables
import Data.Kind
data F (k :: * -> *) where
data G :: F k -> * where
G :: G x
Ten typ danych kompiluje dobrze. Jeśli jednak chcemy określić rodzaj x
w konstruktorze G
, otrzymamy błąd typu.
data H :: F k -> * where
H :: forall k' (x :: F k'). H x
Komunikat o błędzie jest
• Kind variable ‘k’ is implicitly bound in datatype ‘H’, but does not appear as the kind of any of its type variables. Perhaps you meant to bind it (with TypeInType) explicitly somewhere? • In the data declaration for ‘H’
Jeśli dodamy forall
do podpisu naturze (z lub bez forall
w konstruktorze), nie ma błędu.
data I :: forall k. F k -> * where
I :: I x
data J :: forall k. F k -> * where
J :: forall k' (x :: F k'). J x
Co się dzieje?
naprawdę doskonała gra słów. A + – rampion
Wygląda na to, że pierwsza deklaruje "F k", która ma być ustalona dla całej deklaracji, podczas gdy druga pozwala na użycie 'H' w swojej własnej deklaracji w różnych rodzajach. To znaczy. umożliwia polikindową rekursję. Może być podobny do rozróżnienia "parametry vs wskaźniki" w typach indukcyjnych (jak w Agdzie/Coq). – chi
Wygląda na to, że może to być (ostatnio naprawiony) błąd kompilatora. Mogę zduplikować twój komunikat o błędzie za pomocą "ghc-8.0.1", ale kompiluje się dobrze z "ghc-8.0.1.20161117", najnowszą wersją, którą "stack" postanowił zainstalować dla mnie (i która wydaje się być kandydatem do wydania na 8.0 .2). –