相关疑难解决方法(0)

我怎样才能在状态monad中正确添加"撤消"功能?

假设我有一个状态monad,我想对状态进行一些操作,并且可能希望在将来撤消更改.我一般可以这样做得体面吗?

举一个具体的例子,让我们假设状态只是一个Int,操作就是将数字增加一个.

type TestM a = StateT a IO ()

inc :: TestM Int
inc = modify (+ 1)
Run Code Online (Sandbox Code Playgroud)

但是,如果我想跟踪状态的所有历史记录,以防我想要撤消到某个先前的状态,我能想到的最好的方法是将状态包装在堆栈中:对状态的每次修改都会被推送到堆栈,以便我可以通过删除堆栈上的顶部元素来撤消更改.

-- just for showing what's going on
traceState :: (MonadIO m, MonadState s m, Show s) => m a -> m a
traceState m = get >>= liftIO . print >> m

recordDo :: TestM a -> TestM [a]
recordDo m = do
    x <- gets head
    y <- liftIO $ execStateT m x
    modify (y:)

inc' :: …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

14
推荐指数
1
解决办法
568
查看次数

Contt Monad:将各个部分放在一起

前言

我试图围绕如何实际使用ContTcallCC有用的东西.我无法跟踪代码周围的信息和控制流程.(但是,这不是延续的意义吗?)

有很多不同的方法可以用这个monad和少量非常直接的组合器来移动碎片.我将承认我对ContT的工作方式的理解仍感到不安,但我会指出我到目前为止所阅读的内容:

我想做的是发布一个psudo-code示例,然后询问一些有关它的问题.这代表使用ContT的典型代码外观

Psudo码

type MyMonad r = ContT r (State SomeState)

main = do
  runState s_init $ runContT block print

block :: MyMonad r a0
block = do
  before_callcc
  output <- callCC $ \k -> do
    rval <- inner_block
    return rval
  after_callcc
Run Code Online (Sandbox Code Playgroud)

问题

  1. 是什么决定了它的价值和类型output
  2. b这种类型的意思是k什么?
  3. 给予的价值在k哪里?
  4. 什么时候inner_block运行?它看到的是什么版本的州?
  5. 哪里rval去了,它的类型是什么?
  6. k和之间有什么关系rval? …

continuations haskell callcc

9
推荐指数
1
解决办法
445
查看次数

无法获得MonadWriter实例用于连续Monad变压器?

我尝试为Continuation Monad Transformer的MonadWriter创建一个派生实例.这是我尝试的方式:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}

import Control.Monad.Cont
import Control.Monad.Writer


instance (MonadWriter w m) => MonadWriter w (ContT r m) where
   tell= lift . tell
   listen m= ContT $ \ c -> do
         (a,w) <- listen $ runContT m (c)
         return (a,w)

   pass m = undefined
Run Code Online (Sandbox Code Playgroud)

这给了我以下错误:

Occurs check: cannot construct the infinite type: r = (r, w1)
When generalising the type(s) for `listen'
In the instance declaration for `MonadWriter w (ContT r m)'
Run Code Online (Sandbox Code Playgroud)

接下来尝试是这样的:

instance (MonadWriter …
Run Code Online (Sandbox Code Playgroud)

haskell

8
推荐指数
1
解决办法
802
查看次数

StateT over Cont.为什么我的州没有被重置?

我正在玩这里Cont描述的monad技巧和SO问题.

此功能允许您"跳回"到计算中的早期,获取参数,以便您可以采取不同的方式:

import Control.Monad.Cont
import Control.Monad.State.Strict
import Control.Monad.Writer.Strict

getCC' :: MonadCont m => a -> m (a,a -> m b)
getCC' x0 = callCC (\c -> let f x = c (x, f) in return (x0, f))
Run Code Online (Sandbox Code Playgroud)

我有这些monad变换器的玩具示例Cont:

foo :: WriterT String (Cont String) ()
foo = do
    (stop,loop) <- getCC' False
    if stop
        then do tell "bbb"
        else do tell "aaa"
                loop True

foo' :: StateT String (Cont String) ()
foo' = …
Run Code Online (Sandbox Code Playgroud)

monads continuations haskell monad-transformers

5
推荐指数
1
解决办法
108
查看次数

在do块内迭代

我写了这段代码:

toCouplesFile = do inputFile <- openFile "deletedId.csv" ReadMode
                   outputFile <- openFile "couples.txt" WriteMode
                   readAndChange inputFile outputFile

readAndChange i o = do iseof <- hIsEOF i
                       if iseof then (return o)
                       else do line <- hGetLine i
                               hPutStrLn o (show (extractNameAndId line))
                               readAndChange i o
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以使用一个函数重写此代码,使用类似于此模式的东西:

function x = do ...
                label
                .....
                if ... then label else exit
Run Code Online (Sandbox Code Playgroud)

monads haskell

4
推荐指数
1
解决办法
1003
查看次数