标签: monad-transformers

将 MonadError 与 Parsec 结合使用

我正在尝试将 MonadError 与 Parsec 一起使用。我想出了以下代码片段:

f5 = do
    char 'a'
    throwError "SomeError"

f6 = f5 `catchError` (\e -> unexpected $ "Got the error: " ++ e)

ret = runErrorT (runParserT f6 () "stdin" "a")
Run Code Online (Sandbox Code Playgroud)

但是,retis Left "SomeError",似乎 catchError 没有任何效果。在这里使用 MonadError 的正确方法是什么?

我更喜欢使用 MonadError 而不是 Parsec 自己的错误处理,例如当我有:

try (many1 parser1) <|> parser2
Run Code Online (Sandbox Code Playgroud)

如果 parser1 在这里失败, parser2 将继续,但我希望有一个完全中止解析的例外。

monads haskell monad-transformers

3
推荐指数
1
解决办法
1172
查看次数

如何很好地评估嵌套的StateT和ErrorT monad?

我在程序的不同级别有两个类型的控件结构声明.最下面的是Agent一个StateTIO能力的.第二个是StateT具有Agent功能的另一个,第三个是(Plan)是一个ErrorT.

type Agent = StateT AgentState IO
type Plan = ErrorT PlanError (StateT PlanState Agent)
Run Code Online (Sandbox Code Playgroud)

评估a的最佳方法是Plan什么?我写了下面的代码,但它不是很少,因为有大量的嵌套runStateTrunErrorT调用.

foo :: Plan ()
defaultAgentState :: AgentState
runStateT (runStateT (runErrorT foo) (PlanState 0)) defaultAgentState
Run Code Online (Sandbox Code Playgroud)

有更简单/更好的东西吗?

monads haskell monad-transformers

3
推荐指数
1
解决办法
442
查看次数

如何在F#中组合状态和延续monad

我正在尝试使用任务并行库对树进行求和,其中只生成子任务,直到遍历树直到某个深度,否则它使用延续传递样式对剩余的子节点求和,以避免堆栈溢出.

但是,代码看起来很丑陋 - 使用状态monad来承载当前深度会很好,但状态monad不是尾递归.或者,我如何修改继续monad来携带状态?或者创建状态和延续monad的组合?

let sumTreeParallelDepthCont tree cont = 
  let rec sumRec tree depth cont =
    let newDepth = depth - 1
    match tree with
    | Leaf(num) -> cont num
    | Branch(left, right) ->
      if depth <= 0 then
        sumTreeContMonad left (fun leftM ->
          sumTreeContMonad right (fun rightM ->
            cont (leftM + rightM )))
      else 
        let leftTask = Task.Factory.StartNew(fun () -> 
              let leftResult = ref 0
              sumRec left newDepth (fun leftM -> 
                leftResult := leftM)
              !leftResult
              )
        let rightTask = …
Run Code Online (Sandbox Code Playgroud)

monads f# state monad-transformers continuation

3
推荐指数
1
解决办法
483
查看次数

Haskell:为什么这个monad转换错了?

我正在研究monad变形金刚,我读了这篇关于如何避免lifts的帖子.

我的想法是,MonadIO有单子在其中IO可以嵌入,并MonadWriter w有单子在其中WriterT w可以嵌入.所以我编写了下面的代码(读取,累积和记录数字,直到我们得到零),其中使用explicit的工作版本lift在注释中.但GHC抱怨道.我究竟做错了什么?

{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.IO.Class
import Control.Monad.Writer.Class (MonadWriter)
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Writer

-- f :: ReaderT Int (WriterT [String] IO) Int
-- m1 = ReaderT, m2 = WriterT
f :: (MonadWriter [String] m1, MonadIO m2) => m1 (m2 (IO Int))
f = do
    s <- liftIO getLine
    tell ["Input: " ++ s] -- lift $ tell ["Input: " ++ s]
    let …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming monad-transformers

3
推荐指数
1
解决办法
217
查看次数

如何调用部分非巢式变压器?

由于变压器的嵌套:: T2 of T1 of M0,我该怎么利用:: T2 of M0,:: M2

这是一个例子:我正在编写一些需要读取,记录和状态的函数.定义:

gameRoutine :: WriterT [String] (ReaderT Env (State Viable)) NUM
Run Code Online (Sandbox Code Playgroud)

如果我想打个电话 stateFunction :: State Viable NUM

甚至stateWithReaderFunction :: ReaderT Env (State Viable) NUM,

我可以用lift:

gameRoutine = do
    x <- lift . lift $ stateFunction
    y <- lift $ stateWithReaderFunction
Run Code Online (Sandbox Code Playgroud)

但是我怎么打电话writerFunction :: Writer [String] a

writerStateFunction :: WriterT [String] (State Viable) NUM该如何调用(gameRoutine定义之间的区别是ReaderT缺少图层)?

显然,我不想将他们的定义提升为其中之一 …

monads haskell monad-transformers

3
推荐指数
1
解决办法
76
查看次数

跳过monad中的剩余动作 - 就像返回一样

嗨,我正在寻找一种允许monad堆栈跳过剩余动作的好方法,而不会完全跳过.有点像returnC系列语言.

例如,假设我正在使用monadic动作来产生副作用

type MyMonad = ??
doStuff :: MyMonad ()
doStuff = do
   r <- doSomething

   -- equivalent to if (r == "X") return; in C
   dontGoPastHereIf (r == "X")

   doSomeSideEffects r
Run Code Online (Sandbox Code Playgroud)

所以我希望它只能doSomeSideEffects在某些条件下执行.

我知道你可以做一些接近这个与guardwhen了.虽然可以没有嵌套吗?

ExceptT已允许您退出正常流程并返回早期结果.但是ExceptT错误/跳过会传播.我想只跳过本地函数中的其余步骤

doTwoSteps :: MyMonad ()
doTwoSteps = do
  -- if I used ExceptT, an error in the first function will skip the second.
  -- But I still want to do the second step here
  doStuff …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers

3
推荐指数
2
解决办法
253
查看次数

在计算期间在环境中隐式携带STRef

我正在研究一些需要在某些关键时刻使用可变数据的更大计算.我想尽可能地避免使用IO.我的模型使用的constist ExceptT超过ReaderTState数据类型,现在我要替换State有提及ST.

为了简化,假设我想保持单一STRefInt整个计算过程中,让我们跳过ExceptT外层.我最初的想法是STRef s Int进入ReaderT环境:

{-#LANGUAGE Rank2Types#-}
{-#LANGUAGE ExistentialQuantification#-}

data Env = Env { supply :: forall s. STRef s Int }
data Comp a = forall s. Comp (ReaderT Env (ST s) a)
Run Code Online (Sandbox Code Playgroud)

评估员:

runComp (Comp c) = runST $ do
   s <- newSTRef 0
  runReaderT c (Env {supply = s})  -- this is of type `ST s a`
Run Code Online (Sandbox Code Playgroud)

......它失败了,因为 …

monads haskell design-patterns monad-transformers

3
推荐指数
1
解决办法
74
查看次数

Kotlin 将 List&lt;Triple&lt;String, String, String&gt; 变异为 Triple&lt;List&lt;String&gt;, List&lt;String&gt;, List&lt;String&gt;&gt; 的优雅方式

我想尽可能简洁地(但清楚地)将 a 转换List<Triple<String, String, String>为 a Triple<List<String>, List<String>, List<String>>

例如,假设执行转换的方法被调用turnOver,我希望:

val matches = listOf(
  Triple("a", "1", "foo"),
  Triple("b", "2", "bar"),
  Triple("c", "3", "baz"),
  Triple("d", "4", "qux")
)
val expected = Triple(
  listOf("a", "b", "c", "d"),
  listOf("1", "2", "3", "4"),
  listOf("foo", "bar", "baz", "qux")
)
matches.turnOver() == expected // true
Run Code Online (Sandbox Code Playgroud)

如何编写简洁、清晰且可能具有turnOver功能性的函数?

可以使用 Arrow-Kt,我已经将其作为项目依赖项。

monads functional-programming monad-transformers kotlin arrow-kt

3
推荐指数
1
解决办法
452
查看次数

为什么 ParsecT 没有 MonadWriter 实例?

今天早些时候我正在写一些 Haskell。想出了一些类似的东西

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Foo a = Foo { ParsecT String () (Writer DefinitelyAMonoid) a }
    deriving (Functor, Applicative, Monad, MonadWriter DefinitelyAMonoid)
Run Code Online (Sandbox Code Playgroud)

这没有编译。“没有(MonadWriter DefinitelyAMonoid (ParsecT String () (Writer DefinitelyAMonoid)))从数据类型声明的‘派生’子句引起的实例”,GHC 告诉我。所以我决定看看其他一些 MTL 类是否可行,他们确实做到了。ReaderMonadReaderWriterMonadWriter。所以我转身被 Discord 用户引导到Hackage,问题很明显:

MonadState  s m => MonadState  s (ParsecT s' u m)
MonadReader r m => MonadReader r (ParsecT s  u m)
MonadError  e m => MonadError  e (ParsecT s  u …
Run Code Online (Sandbox Code Playgroud)

monads haskell parsec monad-transformers

3
推荐指数
1
解决办法
74
查看次数

在链的末尾惯用地返回一个 Maybe

我有以下代码片段,它有点工作:

launchTask :: (DeviceRepo m) => TaskSpec -> m (Maybe Task)
launchTask taskSpec@TaskSpec { taskSpecImage = image
                             , taskSpecRequirement = requirement
                             } = do
  mayDevice <- getDeviceMatchingRequirement requirement
  case mayDevice of
    Nothing -> return Nothing
    Just device -> do
      mayContainer <- createContainer device requirement
      case mayContainer of
        Nothing -> return Nothing
        Just container ->
          return $
          Just
            Task
              { taskName = pack image
              , taskStatus = TaskStatusRunning
              , taskSpec = taskSpec
              , taskContainerId = containerId container
              }

Run Code Online (Sandbox Code Playgroud)

但是,我觉得这不是很地道。堆叠主要计算(来自 DeviceRepo m)和可能的 …

monads haskell monad-transformers

3
推荐指数
1
解决办法
99
查看次数