{-# LANGUAGE TypeFamilies, DataKinds, PolyKinds, UndecidableInstances #-} module T6018failclosed where -- Id is injective... type family IdClosed a = result | result -> a where IdClosed a = a -- ...but despite that we disallow a call to Id type family IdProxyClosed (a :: *) = r | r -> a where IdProxyClosed a = IdClosed a data N = Z | S N -- PClosed is not injective, although the user declares otherwise. This -- should be rejected on the grounds of calling a type family in the -- RHS. type family PClosed (a :: N) (b :: N) = (r :: N) | r -> a b where PClosed Z m = m PClosed (S n) m = S (PClosed n m) -- this is not injective - not all injective type variables mentioned -- on LHS are mentioned on RHS type family JClosed a b c = r | r -> a b where JClosed Int b c = Char -- this is not injective - not all injective type variables mentioned -- on LHS are mentioned on RHS (tyvar is now nested inside a tycon) type family KClosed (a :: N) (b :: N) = (r :: N) | r -> a b where KClosed (S n) m = S m -- hiding a type family application behind a type synonym should be rejected type MaybeSynClosed a = IdClosed a type family LClosed a = r | r -> a where LClosed a = MaybeSynClosed a type family FClosed a b c = (result :: *) | result -> a b c where FClosed Int Char Bool = Bool FClosed Char Bool Int = Int FClosed Bool Int Char = Int type family IClosed a b c = r | r -> a b where IClosed Int Char Bool = Bool IClosed Int Int Int = Bool IClosed Bool Int Int = Int type family E2 (a :: Bool) = r | r -> a where E2 False = True E2 True = False E2 a = False -- This exposed a subtle bug in the implementation during development. After -- unifying the RHS of (1) and (2) the LHS substitution was done only in (2) -- which made it look like an overlapped equation. This is not the case and this -- definition should be rejected. The first two equations are here to make sure -- that the internal implementation does list indexing corrcectly (this is a bit -- tricky because the list is kept in reverse order). type family F a b = r | r -> a b where F Float IO = Float F Bool IO = Bool F a IO = IO a -- (1) F Char b = b Int -- (2) -- This should fail because there is no way to determine a, b and k from the RHS type family Gc (a :: k) (b :: k) = r | r -> k where Gc a b = Int