实现高阶效果解释器
Implement higher-order effect interpreter
我正在尝试实现高阶效果的解释器。
我有底效:
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
module Hetchr.Commons.Cat where
import Polysemy
import Polysemy.Internal.Tactics
data In = In
newtype Out = Out Int
deriving stock (Show)
deriving newtype (Num)
data TargetE (m :: Type -> Type) (a :: Type) where
ActA :: In -> TargetE m Out
makeSem ''TargetE
runTargetE :: InterpreterFor TargetE e
runTargetE = interpret $ \case
ActA _ -> return $ Out 1
还有一个高阶效应:
data ProxyE (m :: Type -> Type) (a :: Type) where
ProxyA :: (In -> m Out) -> ProxyE m Out
FunPA :: In -> ProxyE m Out
makeSem ''ProxyE
打算用作:
main :: IO ()
main = print =<< runM (runTargetE $ runProxyE $ proxyA funPA)
我有实施帮手:
proxyAImpl :: Member TargetE r => (In -> Sem r Out) -> Sem r Out
proxyAImpl f = (+) <$> f In <*> actA In
但是,我很难实现:
runProxyE :: Member TargetE r => InterpreterFor ProxyE r
runProxyE = interpretH $ \case
ProxyA f -> do
f' <- bindT f
??? proxyAImpl f'
FunPA x -> liftT $ actA x
我还没有找到很多示例,而且我对这些类型感到困惑,有什么提示吗?
实际上,如果我理解正确的话,你无法创建那种没有多态类型的解释器,因此我必须将我的代码调整为:
proxyAImpl :: (Functor f, Member TargetE r) => (In -> Sem r (f Out)) -> Sem r (f Out)
proxyAImpl f = do
left <- f In
right <- actA In
return $ fmap (+ right) left
runProxyE :: Member TargetE r => InterpreterFor ProxyE r
runProxyE = interpretH $ \case
ProxyA f -> proxyAImpl (runTSimple . f)
FunPA x -> liftT $ actA x
我正在尝试实现高阶效果的解释器。
我有底效:
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -fplugin=Polysemy.Plugin #-}
module Hetchr.Commons.Cat where
import Polysemy
import Polysemy.Internal.Tactics
data In = In
newtype Out = Out Int
deriving stock (Show)
deriving newtype (Num)
data TargetE (m :: Type -> Type) (a :: Type) where
ActA :: In -> TargetE m Out
makeSem ''TargetE
runTargetE :: InterpreterFor TargetE e
runTargetE = interpret $ \case
ActA _ -> return $ Out 1
还有一个高阶效应:
data ProxyE (m :: Type -> Type) (a :: Type) where
ProxyA :: (In -> m Out) -> ProxyE m Out
FunPA :: In -> ProxyE m Out
makeSem ''ProxyE
打算用作:
main :: IO ()
main = print =<< runM (runTargetE $ runProxyE $ proxyA funPA)
我有实施帮手:
proxyAImpl :: Member TargetE r => (In -> Sem r Out) -> Sem r Out
proxyAImpl f = (+) <$> f In <*> actA In
但是,我很难实现:
runProxyE :: Member TargetE r => InterpreterFor ProxyE r
runProxyE = interpretH $ \case
ProxyA f -> do
f' <- bindT f
??? proxyAImpl f'
FunPA x -> liftT $ actA x
我还没有找到很多示例,而且我对这些类型感到困惑,有什么提示吗?
实际上,如果我理解正确的话,你无法创建那种没有多态类型的解释器,因此我必须将我的代码调整为:
proxyAImpl :: (Functor f, Member TargetE r) => (In -> Sem r (f Out)) -> Sem r (f Out)
proxyAImpl f = do
left <- f In
right <- actA In
return $ fmap (+ right) left
runProxyE :: Member TargetE r => InterpreterFor ProxyE r
runProxyE = interpretH $ \case
ProxyA f -> proxyAImpl (runTSimple . f)
FunPA x -> liftT $ actA x