标签: state-monad

Haskell:如何在状态monad之上编写交互式解释器?

我们正在开发一个内部使用状态monad的模型文件系统.我们有一个类型类,其操作如下:

class Monad m => FS m where
  isDirectory  :: Path -> m Bool
  children     :: Path -> m [Path]
  ...
Run Code Online (Sandbox Code Playgroud)

我们正在努力一点点交互式解释,将提供类似的命令cd,ls,cat,等等.解释器中的操作可以这样写:

fsop :: FS m => Operation -> m Response
Run Code Online (Sandbox Code Playgroud)

定义OperationResponse不重要; 如果你愿意,把它们当作弦乐.

我试图解决的问题是在I/O monad中编写一个顶层循环来解释文件系统Operation并打印响应.如果IO是FS的一个实例(也就是说,如果我们直接使用IO monad),生活会很简单:我们可以写

loop :: Path -> IO ()
loop currentDir = do
        op <- getLine
        case read op of
          ChangeDir d -> loop d -- should test 'isDirectory d', but let's not
          Ls …
Run Code Online (Sandbox Code Playgroud)

monads interpreter haskell interactive state-monad

17
推荐指数
3
解决办法
2926
查看次数

为什么简单地使用State monad会导致堆栈溢出?

我正在玩State monad,我不知道在这段简单的代码中是什么导致了堆栈溢出.

import Control.Monad.State.Lazy

tick :: State Int Int
tick = do n <- get
         put $! (n+1)
         return n

million :: Int
million = snd $ runState (mapM_ (const tick) [1..1000000]) 0

main = print million
Run Code Online (Sandbox Code Playgroud)

注意 我只想知道在这段代码中导致问题的原因,任务本身本身并不重要.

stack-overflow monads haskell state-monad

17
推荐指数
1
解决办法
1830
查看次数

是否可以实现`(Applicative m)=> Applicative(StateT sm)`?

我正在努力,Data.Fresh并且Control.Monad.Trans.Fresh,正在进行中.定义用于生成新变量的接口,以及实现此接口的monad变换器.

我最初认为可以Applicative为我实现实例,FreshT v m只有Applicative m存在的唯一要求.但是,我卡住了,似乎我需要Monad m.不相信我的Haskell的福,我再转向变压器包,并且很惊讶我发现Control.Monad.Trans.State.Lazy.Strict:

instance (Functor m, Monad m) => Applicative (StateT s m) where
    pure = return
    (<*>) = ap
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题:是否可以使用以下实例头创建具有等效语义的实例?

instance (Applicative m) => Applicative (StateT s m) where
Run Code Online (Sandbox Code Playgroud)

haskell state-monad monad-transformers

17
推荐指数
3
解决办法
878
查看次数

结合StateT和State monads

让我们说我有一个功能

f :: State [Int] Int
Run Code Online (Sandbox Code Playgroud)

和功能:

g :: StateT [Int] IO Int
Run Code Online (Sandbox Code Playgroud)

我想用fg,并通过他们之间的状态.是否有库函数
StateT (return . runState f)?或者一般来说,给定一个具有相应monad的monad变换器,它有一个库函数吗?

monads haskell state-monad monad-transformers

16
推荐指数
2
解决办法
1726
查看次数

Scala State monad - 结合不同的州类型

我正绕着国家单子行道.琐碎的例子很容易理解.我现在转向一个现实世界的案例,其中域对象是复合的.例如,使用以下域对象(它们没有多大意义,只是纯粹的例子):

case class Master(workers: Map[String, Worker])
case class Worker(elapsed: Long, result: Vector[String])
case class Message(workerId: String, work: String, elapsed: Long)
Run Code Online (Sandbox Code Playgroud)

考虑到Worker作为S类型的State[S, +A]单子它很容易写几个组合子这样的:

type WorkerState[+A] = State[Worker, A]
def update(message: Message): WorkerState[Unit] = State.modify { w =>
    w.copy(elapsed = w.elapsed + message.elapsed,
           result = w.result :+ message.work)
}
def getWork: WorkerState[Vector[String]] = State { w => (w.result, w) }
def getElapsed: WorkerState[Long] = State { w => (w.elapsed, w) }
def updateAndGetElapsed(message: Message): WorkerState[Long] = …
Run Code Online (Sandbox Code Playgroud)

monads state functional-programming scala state-monad

15
推荐指数
1
解决办法
991
查看次数

Haskell的逆向性:从Tardis到RevState

以下程序使用由Tardis monad 提供的向后行进状态.

{-# LANGUAGE RecursiveDo #-}

import Control.Monad.Tardis

lastOccurrence :: Int -> Tardis [Int] () Bool
lastOccurrence x = mdo
  sendPast (x : xs)
  xs <- getFuture
  return (not (elem x xs))

lastOccurrences :: [Int] -> Tardis [Int] () [Bool]
lastOccurrences xs = mapM lastOccurrence xs

main :: IO ()
main =
  print $ flip evalTardis ([], ()) $ lastOccurrences [3,4,6,7,4,3,5,7]
Run Code Online (Sandbox Code Playgroud)

如何用反向状态 monad 替换Tardis monad?根据我的以下提议,main永远循环而不是[False,False,True,False,True,True,True,True]像上面的程序一样打印 .

{-# LANGUAGE RecursiveDo #-}

import Control.Monad.RevState

lastOccurrence …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming lazy-evaluation state-monad

15
推荐指数
1
解决办法
492
查看次数

Haskell Monad变换器堆栈和类型签名

我正在尝试创建一堆monad变换器,并且无法为我的函数获取正确的类型签名.(我对Haskell还很新)

该堆栈结合了多个StateT变换器,因为我有多个状态需要跟踪(其中两个可能是tupled,但我会在一秒内完成)和一个WriterT用于记录.

这是我到目前为止所拥有的:

module Pass1 where
import Control.Monad.Identity
import Control.Monad.State
import Control.Monad.Writer
import Data.Maybe
import qualified Data.Map as Map
import Types

data Msg = Error String
         | Warning String

type Pass1 a = WriterT [Msg] (StateT Int (StateT [Line] (StateT [Address] Identity))) a


runPass1 addrs instrs msgs = runIdentity (runStateT (runStateT (runStateT (runWriterT msgs) 1) instrs) addrs)


--popLine :: (MonadState s m) => m (Maybe s)
--popLine :: (Monad m) => StateT [Line] m (Maybe Line)
popLine :: (MonadState s …
Run Code Online (Sandbox Code Playgroud)

haskell types state-monad monad-transformers

14
推荐指数
2
解决办法
3046
查看次数

Haskell:map runST

我有一个类型的绑定[ST s (Int, [Int])],我试图runST使用map 应用于每个元素,如下所示:

name :: [ST s (Int, [Int])] --Of Course there is a real value here
map runST name
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误信息

Couldn't match expected type `forall s. ST s b0'
    with actual type `ST s0 (Int, [Int])'
Expected type: [forall s. ST s b0]
  Actual type: [ST s0 (Int, [Int])]
In the second argument of `map', namely `name'
In the expression: map runST name
Run Code Online (Sandbox Code Playgroud)

必须有一些我误解的东西.我知道runST和函数组成,但我不确定这是否适用.

谢谢大家的时间!

haskell state-monad

14
推荐指数
3
解决办法
1016
查看次数

Control.Monad.State API最近有变化吗?

作为一个学习练习,我试图在Haskell中实现一个heapsort.我认为Statemonad将是这样做的正确选择,因为堆积很大程度上依赖于在单个结构内部移动数据(并且do符号将是有用的).此外,我希望能够巩固我对monad的理解.

这些示例State单子了解你的Haskell(和数量其他 教程),说的是State被定义为:

newtype State s a = State { runState :: s -> (a,s) }
Run Code Online (Sandbox Code Playgroud)

我应该将类型的函数s -> (a,s)(可能在其他参数中,也可能不在其他参数中)传递给State值构造函数.所以我的函数看起来像这样:

pop :: Ord a => State (Heap a) a
pop = State pop'
pop' :: Ord a => Heap a -> (a, Heap a)
-- implementation of pop' goes here

push :: Ord a => a -> State (Heap a) () …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

14
推荐指数
2
解决办法
2892
查看次数

模拟Haskell中的交互状态对象

我正在编写一个Haskell程序,它涉及模拟一个抽象机器,它具有内部状态,接受输入并提供输出.我知道如何使用状态monad实现这一点,从而产生更清晰,更易于管理的代码.

我的问题是,当我有两个(或更多)有状态对象相互交互时,我不知道如何使用相同的技巧.下面我给出了一个高度简化的问题版本,并勾勒出我到目前为止的内容.

为了这个问题,让我们假设一个机器的内部状态只包含一个整数寄存器,因此它的数据类型是

data Machine = Register Int
        deriving (Show)
Run Code Online (Sandbox Code Playgroud)

(实际的机器可能有多个寄存器,程序指针,调用堆栈等等,但现在不要担心.)在上一个问题之后我知道如何使用状态monad实现机器,所以我不必显式传递其内部状态.在这个简化的示例中,导入后实现如下所示Control.Monad.State.Lazy:

addToState :: Int -> State Machine ()
addToState i = do
        (Register x) <- get
        put $ Register (x + i)

getValue :: State Machine Int
getValue = do
        (Register i) <- get
        return i
Run Code Online (Sandbox Code Playgroud)

这让我可以写出类似的东西

program :: State Machine Int
program = do
        addToState 6
        addToState (-4)
        getValue

runProgram = evalState program (Register 0)
Run Code Online (Sandbox Code Playgroud)

这会将6添加到寄存器,然后减去4,然后返回结果.状态monad跟踪机器的内部状态,以便"程序"代码不必明确跟踪它.

在命令式语言的面向对象样式中,这个"程序"代码可能看起来像

def runProgram(machine):
    machine.addToState(6)
    machine.addToState(-4)
    return machine.getValue()
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果我想模拟两台彼此交互的机器,我可能会写

def …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad lenses haskell-lens

14
推荐指数
2
解决办法
437
查看次数