Wiele ograniczeń wydaje się zbierać. Rozdzielmy je.Fundeps dla rodzin z ograniczeniami
type MonadNumState a m = (MonadState a m, Num a)
MonadNumState
jest po prostu synonimem ograniczenia, więc uzyskać korzyści z zależnościami funkcjonalnymi w każdym użyciu i łatwo rzucać MonadNumState a m
w kontekście. Teraz załóżmy, że chcę to streszczenie w rodzinie więzów:
class Iterator t where
type MonadIter t a m :: Constraint
next :: (MonadIter t a m) => m t
...
instance Iterator Foo where
type MonadIter Foo a m = (MonadState a m, Num a)
...
instance Iterator Bar where
type MonadIter Bar a m = (MonadRandom m, MonadSplit a m, RandomGen a)
...
Ale teraz a
nie jest to zależność funkcjonalna. next
praktycznie nie nadaje się do użytku od a
nie można wywnioskować. Co mogę zrobić? Cóż, mógłbym oczywiście użyć rodziny typów. MonadState
jest napisany przy użyciu programu fundss, ale powinno być łatwe przekształcanie znaków zachęty w typ rodziny.
instance (MonadState s m) => MonadStateFamily m where
type St m = s
get' = get
...
instance (MonadStateFamily m) => MonadState (St m) m where
get = get'
...
Zgadnij, nie.
Foo.hs:25:3:
The RHS of an associated type declaration mentions type variable `s'
All such variables must be bound on the LHS
Co jeszcze mogę zrobić? To, czego naprawdę chcę, to egzystencjalnie określić ilościowo: s
. Nie znalazłem żadnego sposobu na to bez wyraźnego podania słownika.
Jak mogę uzyskać korzyści z fundeps dla rodzin z ograniczeniami?