我正在从许多不同的地方汇集代码,我正在尝试处理以下问题:
我有一个变压器堆栈,具有以下简化类型:
action :: m (ReaderT r IO) a
Run Code Online (Sandbox Code Playgroud)
我正在尝试在不同堆栈的上下文中使用该操作,该堆栈具有不同的读取器环境:
desired :: m (ReaderT r' IO) a
Run Code Online (Sandbox Code Playgroud)
我当然可以提供
f :: r' -> r
Run Code Online (Sandbox Code Playgroud)
things :: m (ReaderT r' IO) ()
things = do
-- ... some stuff
-- <want to use action here>
action :: m (ReaderT r IO) a -- broken
-- ... more stuff
pure ()
Run Code Online (Sandbox Code Playgroud)
withReaderT :: (r' -> r) -> ReaderT r m a -> ReaderT r' m a
Run Code Online (Sandbox Code Playgroud)
这有一个问题,ReaderT是外部monad,而我想在内部使用它.
我也认为这可能与MonadBase或MonadTransControl有关,但我不熟悉它们的工作原理.
我写了以下代码.它正在使用Readermonad.
你能给我一些关于Haskell代码风格的提示吗?主要是我的意思是monads - 我是新手.
import Control.Monad.Reader
data Tree a = Node a (Tree a) (Tree a)
| Empty
renumberM :: Tree a -> Reader Int (Tree Int)
renumberM (Node _ l r) = ask >>= (\x ->
return (Node x (runReader (local (+1) (renumberM l)) x)
(runReader (local (+1) (renumberM r)) x)))
renumberM Empty = return Empty
renumber'' :: Tree a -> Tree Int
renumber'' t = runReader (renumberM t) 0
Run Code Online (Sandbox Code Playgroud) 为什么Control.Monad.Reader中有一个Reader monad和一个MonadReader monad?包文档讨论了Reader monad,然后直接启动MonadReader文档,没有任何解释.这些monad有什么区别?阅读这些参考页面让我感到困惑.有趣的是,Haskell wikibook的Reader monad页面尚未编写!
编辑:p如果存在以下功能f,我们将调用纯箭头:p = arr f。
我试图更好地了解Haskell中的Arrows,我想弄清楚何时
f >>> (g &&& h) = (f >>> g) &&& (f >>> h)其中f,g,h是箭头。
显然,通常情况并非如此。在此特定示例中,副作用在右侧重复:
GHCi> c = Kleisli $ \x -> ("AB", x + 1)
GHCi> fst . runKleisli (c >>> c &&& c) $ 1
"ABABAB"
GHCi> fst . runKleisli ((c >>> c) &&& (c >>> c)) $ 1
"ABABABAB"
Run Code Online (Sandbox Code Playgroud)
显然,f >>> (g &&& h) = (f >>> g) &&& …
在学习Reader Monad时,我发现它被定义为:
newtype Reader r a = Reader { runReader :: r -> a }
instance Monad (Reader r) where
return a = Reader $ \_ -> a
m >>= k = Reader $ \r -> runReader (k (runReader m r)) r
Run Code Online (Sandbox Code Playgroud)
我想知道为什么使用函数作为构造函数参数而不是其他东西,如元组:
newtype Reader r a = Reader { runReader :: (r, a) }
instance Monad (Reader r) where
-- Here I cannot get r when defining return function,
-- so does that's the reason that must using a …Run Code Online (Sandbox Code Playgroud) 在设计编程模型时,我总是会遇到哪种方法更好的难题:
type MyMonad1 = StateT MyState (Reader Env)
type MyMonad2 = ReaderT Env (State MyState)
Run Code Online (Sandbox Code Playgroud)
在使用一个单子与另一个单子之间有什么好处和取舍?有关系吗?性能如何?
我试图将ReaderT X IOmonad 视为 IO 以实现以下目标:
-- this is the monad I defined:
type Game = ReaderT State IO
runGame :: State -> Game a -> IO a
runGame state a = runReaderT a state
readState :: Game State
readState = ask
-- some IO action, i.e. scheduling, looping, etc.
ioAction :: IO a -> IO ()
ioAction = undefined
-- this works as expected, but is rather ugly
doStuffInGameMonad :: Game a -> Game ()
doStuffInGameMonad gameAction …Run Code Online (Sandbox Code Playgroud) 我试图理解什么是 Haskell Reader monad,但我在书中的这一部分很挣扎:
类型参数的“只读”性质
r意味着您可以r为您调用的函数交换不同的类型或值,但不能为调用您的函数交换。证明这一点的最好方法是使用该withReaderT函数,该函数让我们开始一个新的Reader上下文,并提供不同的参数:Run Code Online (Sandbox Code Playgroud)withReaderT :: (r' -> r) -- ^ The function to modify the environment. -> ReaderT r m a -- ^ Computation to run in the modified environment. -> ReaderT r' m a
那么,首先,您能否具体说明什么是“您调用的函数”,什么是“调用您的函数”?
作为练习,我一直在重新实现一些常见的 monad 及其相应的转换器;以下是我定义的一些类型:
newtype Writer w a = Writer { runWriter :: (w, a) }
newtype WriterT w m a = WriterT { runWriterT :: m (Writer w a) }
newtype Maybe a = Just a | Nothing
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
Run Code Online (Sandbox Code Playgroud)
据我所知,变压器将一个单子“包裹”在一个外部单子中m;遵循这种直觉,我尝试ReaderT以类似的方式定义变压器:
newtype Reader r a = Reader { runReader :: r -> a }
newtype ReaderT r m a = ReaderT { runReaderT :: m …Run Code Online (Sandbox Code Playgroud) 我正在开发一个中型 Kotlin 项目,我需要通过纯函数的许多嵌套调用来线程化从文件读取的配置信息。对于 Reader monad 来说,这似乎是一个明显的例子。但是,我还没有弄清楚如何在 Kotlin 中有效地实现 Reader。
我正在使用 Arrow 库 (v1.1.3),但令我惊讶的是,它没有附带 Reader 的实现。使用 Arrow 通过函数调用来线程化配置数据的首选方法是什么?由于 Arrow 已转向使用 Kotlin 的本机挂起系统来理解 monad,我认为这意味着不需要专门的 Reader 实现。该怎么做呢?
reader-monad ×10
haskell ×9
monads ×7
arrow-kt ×1
arrows ×1
kleisli ×1
kotlin ×1
performance ×1
state-monad ×1