Ich glaube nicht, dass diese Tatsache (wie von der Art der fob
angegeben) tatsächlich wahr ist. Aufgrund der Open-World-Eigenschaft von Typklassen können Sie die Fundecke mit Modulgrenzen verletzen.
Dies wird durch das folgende Beispiel gezeigt. Dieser Code wurde nur mit GHC 7.10.3 getestet (fundeps waren in älteren Versionen massiv kaputt - weiß nicht, was dann passiert). Angenommen, Sie in der Tat die folgende implementieren können:
module A
(module A
,module Data.Type.Equality
,module Data.Proxy
)where
import Data.Type.Equality
import Data.Proxy
class C a b | a -> b
inj_C :: (C a b, C a b') => Proxy a -> b :~: b'
inj_C = error "oops"
dann noch ein paar Module:
module C where
import A
instance C() Int
testC :: C() b => Int :~: b
testC = inj_C (Proxy :: Proxy())
und
module B where
import A
instance C() Bool
testB :: C() b => b :~: Bool
testB = inj_C (Proxy :: Proxy())
und
module D where
import A
import B
import C
oops :: Int :~: Bool
oops = testB
oops_again :: Int :~: Bool
oops_again = testC
Int :~: Bool
ist eindeutig nicht wahr , so vorbei Widerspruch, inj_C
kann nicht existieren.
Ich glaube, Sie können inj_C
mit unsafeCoerce
immer noch sicher schreiben, wenn Sie nicht die Klasse C
aus dem Modul exportieren, wo es definiert ist. Ich habe diese Technik benutzt, habe es ausgiebig versucht und konnte keinen Widerspruch schreiben. Nicht zu sagen, es ist unmöglich, aber zumindest sehr schwierig und ein seltener Randfall.
Wenn Sie das fundep als 'Klasse (F a ~ b) => C ab kodieren, wo Typ F a' wie in [GHC docs] beschrieben (https://downloads.haskell.org/~ghc/7.8. 4/docs/html/users_guide/Gleichheitseinschränkungen.html), dann funktioniert es. Aber das fühlt sich an wie Betrug, weil man eine Gleichheitsbeschränkung einführt, während man fragt, ob man etwas herausholen kann ... –
@JonPurdy, tatsächlich, in beiden Hinsichten. – dfeuer
Am ärgerlichsten kann GHC nicht einmal herausfinden, dass das eine das andere impliziert. Der Versuch, von der Version fundep in die Version type family zu wechseln, bietet keine Möglichkeit, die erforderliche Typfamilie zu erstellen. Der Versuch, von der Typ-Familienversion in die Fundep-Version zu wechseln, scheitert an der liberalen Deckungsbedingung (was ich so interpretiere, dass man sieht, dass sie die Funde nicht befriedigt). – dfeuer