我正在将代码库转换为使用polysemy ,并且在转换我对LFresh
typeclass 的unbound-generics
使用时遇到了麻烦。我需要的两个操作都有签名
avoid :: LFresh m => [AnyName] -> m a -> m a
lunbind :: (LFresh m, Alpha p, Alpha t) => Bind p t -> ((p, t) -> m c) -> m c
这显然是高阶的。我想创建一个与LFresh
该类对应的效果,并LFreshM
通过unbound-generics
. 到目前为止,这是我尝试过的,Final
因为这似乎让我比父亲更喜欢Embed
(我很高兴LFreshM
一直是效果堆栈中的最后一件事):
import Polysemy
import Polysemy.Final
import qualified Unbound.Generics.LocallyNameless as U
data LFresh m a where
Avoid :: [U.AnyName] -> m a -> LFresh m a
LUnbind :: (U.Alpha p, U.Alpha t) => U.Bind p t -> ((p,t) -> m c) -> LFresh m c
makeSem ''LFresh
runLFresh :: Member (Final U.LFreshM) r => Sem (LFresh ': r) a -> Sem r a
runLFresh = interpretFinal @U.LFreshM $ \case
Avoid xs m -> do
m' <- runS m
pure (U.avoid xs m')
LUnbind b k -> do
k' <- bindS k
pure (U.lunbind b k')
但是, case forLUnbind
不进行类型检查,因为k' :: f (p, t) -> U.LFreshM (f x)
它期望某种类型(p, t) -> U.LFreshM (f x)
作为 ; 的第二个参数U.lunbind
。f
注意类型中的额外内容k'
。
我还有其他模糊的想法,但我暂时将其留在那里,很高兴进一步澄清。甚至不确定我是否走在正确的轨道上。最终,我的真正目标只是“让多义词与LFresh
from一起工作unbound-generics
”,所以如果有更好的、完全不同的方法来实现,我也很高兴听到它。