Functional Dependencies in a Specific Case

For an introduction, see this question and my answer . In the end, I note that it seems that you can remove the need for extraneous type specification with a functional dependency. Here is the code in its current form:

{-# LANGUAGE GADTs, MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}

data Nil
data TList a b where
    TEmpty :: TList Nil Nil
    (:.) :: c -> TList d e -> TList c (TList d e)
infixr 4 :.

class TApplies f h t r where
    tApply :: f -> TList h t -> r

instance TApplies a Nil Nil a where
    tApply a _ = a

instance TApplies f h t r => TApplies (a -> f) a (TList h t) r where
    tApply f (e :. l) = tApply (f e) l]

Now, the intuitive thing for me seems to be to add fundep f h t -> rto the class TApplies. However, when I do this, the GHC complains about the recursive instance TAppliesas follows:

Illegal instance declaration for
β€˜TApplies (a -> f) a (TList h t) r’
The coverage condition fails in class β€˜TApplies’
   for functional dependency: β€˜f h t -> r’
Reason: lhs types β€˜a -> f’, β€˜a’, β€˜TList h t’
   do not jointly determine rhs type β€˜r’

The last two lines seem to me wrong, although, I think, I just misunderstand something. My reasoning is this:

  • If we have a -> fand athen we have f.
  • If we have TList h t, then we have hand t.
  • TApplies f h t r, fundep f h t -> r.
  • , f, h t, r.

, . - , , , ? ( , - f r -> h GHC, , , .)

+4
1

-, , , . , .

:

data TList (xs :: [*]) where 
  Nil :: TList '[]
  (:.) :: x -> TList xs -> TList (x ': xs) 

infixr 4 :.

:

class TApplies f (xs :: [*]) r | f xs -> r where ...

instance TApplies g ys q => TApplies (y -> g) (y ': ys) q where 

( , ), , , : " " TApplies ". , " "? :

. tvsleft β†’ tvsright, , S (tvsright) S (tvsleft), S - .

, , - , {q}, - {y, g, ys}. , , .

, . ! , . , , instance TApplies (y -> g) (y ': ys) q where ..., .

: {-# LANGUAGE UndecidableInstances #-} . , , , . UndecidableInstances, : " , ".


, . , tApply (+) (1 :. 2 :. Nil) " " - . , tApply (+) (1 :. "s" :. Nil) " "! , . , .

, :

instance (a ~ a') => TApplies a '[] a' where
instance (TApplies g ys q, y ~ y') => TApplies (y -> g) (y' ': ys) q where 

, defaulting kicks in "3". No instance for (Num [Char]), .

, , , , . instance TApplies (y -> g) (y' ': ys) q - , , , , y y' , . , , , y ~ y', (+) 1 2.


:

{-# LANGUAGE GADTs #-}
data Cons a b 
data Nil

data TList xs where
  Nil  :: TList Nil
  (:.) :: x -> TList xs -> TList (Cons x xs)

, DataKinds .

+4

All Articles