mirror of
https://github.com/lexi-lambda/freer-simple.git
synced 2024-12-23 14:12:45 +03:00
Change LastMember to cooperate better with rigid vars and local dicts
The use of a closed type family works well when the entire effect list is known, but when it’s quantified over, the closed type family gets stuck (since the effect list is rigid). Sometimes this is okay, since it simply means the LastMember constraint is insoluble, but can be satisfied if an explicit constraint brings a local LastMember dictionary into scope. Performing the recursion directly in the instance avoids this problem, though it does require overlapping instances. fixes #6
This commit is contained in:
parent
a2ae7109ad
commit
99e26fae04
@ -61,10 +61,6 @@ type family Members effs effs' :: Constraint where
|
||||
Members (eff ': effs) effs' = (Member eff effs', Members effs effs')
|
||||
Members '[] effs' = ()
|
||||
|
||||
type family Last effs where
|
||||
Last (eff ': '[]) = eff
|
||||
Last (_ ': effs) = Last effs
|
||||
|
||||
-- | Like 'Member', @'LastMember' eff effs@ is a constraint that requires that
|
||||
-- @eff@ is in the type-level list @effs@. However, /unlike/ 'Member',
|
||||
-- 'LastMember' requires @m@ be the __final__ effect in @effs@.
|
||||
@ -74,5 +70,6 @@ type family Last effs where
|
||||
-- in combination with 'Control.Monad.Freer.sendM' or
|
||||
-- 'Control.Monad.Base.liftBase' to embed ordinary monadic effects within an
|
||||
-- 'Control.Monad.Freer.Eff' computation.
|
||||
class (Member m effs, m ~ Last effs) => LastMember m effs | effs -> m
|
||||
instance (Member m effs, m ~ Last effs) => LastMember m effs
|
||||
class Member m effs => LastMember m effs | effs -> m
|
||||
instance {-# OVERLAPPABLE #-} LastMember m effs => LastMember m (eff ': effs)
|
||||
instance LastMember m (m ': '[])
|
||||
|
Loading…
Reference in New Issue
Block a user