Istnieje wiele zalet posiadania typologii w formularzu C a Bool
. Głównie dlatego, że pozwalają wykonać dowolną operację logiczną między dwoma wiązaniami, gdy normalny C a
po prostu niejawnie AND wszystko.Konwersja dowolnego ograniczenia klasy "C a" na "C a Bool"
Jeśli weźmiemy pod uwagę ~
ograniczenie klasy, można to zrobić jak tak
class Equal x y b | x y -> b
instance Equal x x True
instance False ~ b => Equal x y b
ale to, co sprawia, że to przypadek szczególny, jest fakt, że wprowadzenie x x
w głowie instancji jest równoważna x ~ y =>
a następnie x y
w głowie. Nie dotyczy to żadnej innej typografii. Więc jeśli staramy się zrobić coś podobnego dla klasy C
otrzymujemy coś
class C' x b | x -> b
instance C x => C' x True
instance False ~ Bool => C' x b
Niestety to nie działa, ponieważ tylko jeden z tych przypadków będzie kiedykolwiek podniósł, bo nie dyskryminuje typu x
więc każdy typ pasuje do obu głów.
Przeczytałem również https://www.haskell.org/haskellwiki/GHC/AdvancedOverlap, który ponownie nie dotyczy żadnej klasy C
, ponieważ wymaga przepisania wszystkich wystąpień oryginalnej klasy. Najlepiej byłoby, gdyby mój kod działał z GHC.Exts.Constraint
i KindSignatures
, aby C
mógł być parametryczny.
Więc dla klasy jak ten
class Match (c :: * -> Constraint) x b | c x -> b
Jak napisać przypadki tak że Match c x True
wtedy i tylko wtedy c x
, Match c x False
inaczej?
Opcja 'C formą Bool' jest silniejsza niż' C A'.Zasadniczo pytasz, jak zebrać zestaw wystąpień klasy typu, co jest niemożliwe. – user2407038
@ user2407038 Nie żebym wątpił w ciebie, ale słyszałem "niemożliwe" w odniesieniu do systemu typu wcześniej i okazało się, że jest fałszywe. –
Nie wiem, czy mogę przekonująco argumentować, ale spróbuję. Załóżmy, że napisałeś "Match". W module A definiuję "dane X = X" i "klasa A b x | b -> x; a :: Proxy b -> x; instance A True Int; instancja A False Bool', 'test :: forall x b y. (Dopasuj równanie x b, A b y) => x -> y; test _ = a (Proxy :: Proxy b) '. Mam moduł B (import A), w którym typem "testu X" musi być "Int". W module C (import A) mam 'instance Eq X', więc' test X :: Bool'. Moduł D importuje B i C. Moduł D nie może nie zmusić B i C do rekompilacji, więc 'test X' musi paradoksalnie mieć dwa typy naraz. – user2407038