В качестве введения см. this question и my answer. В конце я отмечаю, что кажется, что вы можете удалить необходимость в посторонней спецификации типа с функциональной зависимостью. Вот код, как он стоит:Функциональные зависимости в конкретном случае
{-# 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]
Теперь, интуитивная вещь для меня, чтобы сделать, кажется, добавить fundep f h t -> r
к TApplies
класса типов. Однако, когда я делаю это, GHC жалуется на возвратном экземпляре TApplies
следующим образом:
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’
Последние две строки, кажется мне неправильным, хотя я ожидаю, что я просто неправильно понять что-то. Мои рассуждения заключается в следующем:
- Если мы имеем
a -> f
иa
, то мы имеемf
. - Если у нас есть
TList h t
, то у нас естьh
иt
. - Поскольку у нас есть
TApplies f h t r
, у нас есть fundepf h t -> r
. - Поэтому, поскольку у нас есть
f
,h
иt
, у нас естьr
.
Это подразумевает, что функциональная зависимость является satified. Может ли кто-то указать на недостаток в моей логике, а также, возможно, предложить более подходящий выбор функциональной зависимости? (Обратите внимание, что что-то вроде разрешено GHC, но, похоже, не дает большого количества указаний по типу.)
Параметр 'r' на самом деле кажется мне лишним, если все« TLists »заканчиваются в« TList Nil Nil », тогда' f ~ r' всегда истинно, не так ли? – Cubic
Nevermind. Я написал то, что вы пытаетесь сделать в терминах, с которыми мне больше знакомы, и теперь я понимаю, что вы пытаетесь сделать, и сталкиваетесь с той же проблемой. Я посмотрю, не могу ли я найти решение или объяснение, или и то, и другое. – Cubic