4

我正在将代码库转换为使用polysemy ,并且在转换我对LFreshtypeclass 的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.lunbindf注意类型中的额外内容k'

我还有其他模糊的想法,但我暂时将其留在那里,很高兴进一步澄清。甚至不确定我是否走在正确的轨道上。最终,我的真正目标只是“让多义词与LFreshfrom一起工作unbound-generics”,所以如果有更好的、完全不同的方法来实现,我也很高兴听到它。

4

1 回答 1

2

在阅读了一些博客文章后,例如https://reasonablypolymorphic.com/blog/freer-higher-order-effects/index.htmlhttps://reasonablypolymorphic.com/blog/tactics/index.html我想我明白了。我只需要使用getInitialStateS来获取f (),然后使用冰淇淋运算符<$(p,t)值注入到f上下文中,然后再将其传递给bindT. 我被暗示使用类似getInitialStateS的东西更高级并且应该避免的评论吓到了,但是现在我更好地理解了正在发生的事情,我认为这正是这种情况下的正确工具。这是生成的代码。它会进行类型检查,尽管我还不能实际测试它。

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
    s <- getInitialStateS
    k' <- bindS k
    pure (U.lunbind b (k' . (<$ s)))
于 2021-07-15T16:17:02.967 回答