我正在尝试构建以下类型的Monad
实例:
data CmdY ρ η ω = CmdY (Reader ρ ((Stream (Of CmdSpec) η ω)))
其中Stream
和Of
来自Streaming
程序包中的streaming
。
我已经成功编写了Functor
Applicative
个实例:
instance (Monad η) => Functor (CmdY ρ η) where
fmap :: (α -> β) -> CmdY ρ η α -> CmdY ρ η β
fmap f (CmdY a) = CmdY $ (fmap f) <$> a
instance (Monad η) => Applicative (CmdY ρ η) where
pure = CmdY . pure . return
(<*>) :: CmdY ρ η (α -> β) -> CmdY ρ η α -> CmdY ρ η β
(CmdY f) <*> (CmdY a) = let ff = (<*>) <$> f
in CmdY $ ff <*> a
但是我正在绕圈子尝试实现Monad的绑定(>>=)
。
我有一个函数来评估CmdY并给我一个流和结果:
runCmdY :: (MonadIO η, MonadIO μ, MonadReader (ProcExecCtxt μ) ψ) =>
CmdY (ProcExecCtxt μ) η ω -> ψ (Stream (Of CmdSpec) η ω)
但是给定形式为a >>= f
的绑定,a的类型为CmdY (ProcExecCtxt η) η α
,而f的类型为α -> CmdY (ProcExecCtxt η) η β
,我需要获取类型为α的东西来馈入我的f,而且我没能到达那里。
ProcExecCtxt m
是执行上下文;它提供了一种评估单子m中cmds的方法。
我确定我遗漏了一些显而易见的东西(或者至少,我希望一旦看到它就会变得显而易见);但是我很感谢任何指针。
谢谢
答案 0 :(得分:3)
cy.on('select', 'node', function (evt) {}
真的只是
cy.on('select', 'node', function (evt) {
let selectedElements = cy.elements(':selected');
let selectedIds = [];
for (let i = 0; i < selectedElements.length; i++) {
selectedIds.push(selectedElements[i].id())
}
console.log("selected elements:", selectedElements[0].json());
if (selectedElements.length === 1) {
let selElem = selectedElements[0].json();
let vals = selElem.data.id.split("_");
sendMessage(FROM_MODELER_ACTION_SELECTED_TO_DASHBOARD, {
id: vals[0],
gId: vals[1],
name: selElem.data.name
})
}
}
在这种情况下,还有第三种拼写该类型的方法可能更有意义:
Reader ρ (Stream (Of CmdSpec) η ω)
使用 ρ -> Stream (Of CmdSpec) η ω
(也由ReaderT ρ (Stream (Of CmdSpec) η) ω
导出),这是定义的monad转换器
Control.Monad.Trans.Reader.ReaderT
由于Control.Monad.Reader
是monad转换器,所以newtype ReaderT e m a = ReaderT
{ runReaderT :: e -> m a }
是ReaderT e
时的monad。因此,它将免费提供您想要的所有实例以及更多实例。确实,使用
ReaderT e m
你可以写
m
或者,如果愿意,可以通过包装和展开{-# language GeneralizedNewtypeDeriving #-}
来手动定义实例:
newtype CmdY ρ η ω = CmdY
{ unCmdY :: ReaderT ρ (Stream (Of CmdSpec) η) ω }
deriving (Functor, Applicative, Monad
, Alternative, MonadPlus, MonadReader ρ)
CmdY
本身就是monad转换器:
instance Monad η => Functor (CmdY ρ η) where
fmap f (CmdY m) = CmdY (fmap f m)
instance Monad η => Applicative (CmdY ρ η) where
pure = CmdY . pure
CmdY fs <*> CmdY xs = CmdY (fs <*> xs)
instance Monad η => Monad (CmdY ρ η) where
CmdY m >>= f = CmdY $ m >>= unCmdY . f
答案 1 :(得分:0)
Data.Functor.Compose
实现您的Functor
和Applicative
实例。
ReaderT
为您实现了一个Monad
实例。