Haskell: определение типа при использовании функциональных зависимостей с семействами типов и GADT

Мне пришлось использовать множество расширений, чтобы создать безопасное представление встроенного языка в Haskell. В какой-то момент, когда я ввел взаимную функциональную зависимость, вывод типа остановился, чтобы выяснить правильные замены для переменных типа. См. пример ниже:

-- create a bidirectional connection between Unit' and ()
class Connect t r | t -> r, r -> t where
data Unit'
instance Connect Unit' () where

-- define a GADT that has only a MyGADT Unit' instance
data MyGADT t where
  MyGADT :: () -> MyGADT Unit'

class Clas a where
  type RetTyp a :: *
  eval' :: Connect (RetTyp a) r => a -> r

instance Clas (MyGADT t) where
  type RetTyp (MyGADT t) = t
  eval' (MyGADT a) = a -- cannot figure out that "a :: ()"

Интересно то, что когда я использовал TypeFamily для Connect, все было в порядке:

class Connect' t where
  type Repr t :: *

instance Connect' Unit' where
  type Repr Unit' = ()

class Clas' a where
  type RetTyp' a :: *
  eval'' :: Connect' (RetTyp a) => a -> (Repr (RetTyp' a))

instance Clas' (MyGADT t) where
  type RetTyp' (MyGADT t) = t
  eval'' (MyGADT a) = a -- ok

В чем разница между разрешением типа в двух случаях?


person Boldizsár Németh    schedule 10.10.2013    source источник
comment
Взгляд на это может помочь stackoverflow.com/questions/12407215/   -  person Satvik    schedule 10.10.2013
comment
вам нужен другой связанный тип, чтобы выразить эту функциональную зависимость: class (UnRepr (Repr t) ~ t) => Connect' t where type Repr t; type UnRepr r   -  person aavogt    schedule 10.10.2013