标签: state-monad

State和其他MTL monad的应用实例?

查看文档Control.Applicative,我注意到它们具有某些monad的实例声明(例如IO,Maybe特别是ST),但是没有MTL monad的实例,例如StateRWS.相反,它看起来像是WrappedMonad定义了一个通用类型,我猜测它是涵盖所有其他情况.

所以这是我的问题:

  1. 为什么没有ApplicativeMTL monad的实例?到目前为止,我自己能够找到的最好的答案是一个三年前的帖子,有人实现了这些实例,并被忽略了.

  2. 有什么处理WrappedMonad?我在Reddit上发现了一篇简短解释的帖子,但我觉得我对如何使用它很困惑.

最终我希望能够以State一种适用的方式使用(如推荐的那样),但如果我不得不用WrappedMonad数据构造函数丢弃我的代码,那么它似乎不是一个胜利.我也可以不理会WrappedMonad完全,并定义Applicative实例自己,是为做了同样的方式IO,ST等等:在以下方面returnap......但似乎愚蠢的为好.

haskell state-monad applicative

6
推荐指数
1
解决办法
1014
查看次数

haskell中不同的,相互作用的状态水平

我正在模拟一个4位微处理器.我需要跟踪寄存器,内存和运行输出(还有一个获取 - 执行周期计数器的奖励点).我已经设法在没有monad的情况下做到了这一点,但是一下子明确地传递那么多东西感觉很乱.函数定义也很混乱,冗长且难以阅读.

我试图用monad做这个,它只是不适合在一起.我尝试将所有单独的状态组件视为单一类型,但这给我留下了产生价值的问题.

State Program () -- Represents the state of the processor after a single iteration of the fetch execute cycle
Run Code Online (Sandbox Code Playgroud)

是唯一有意义的类型.但那时为什么甚至打扰?我尝试通过从我的复合类型中拉出字符串并将其作为值来对其进行分解

State Program' String
Run Code Online (Sandbox Code Playgroud)

除了我需要RUNNING输出这一事实外,它工作得很好.无论我做了什么,我都无法同时保持弦乐和状态.

现在我正在努力解决monad变形金刚问题.似乎我必须将所有不同级别的州分开.但我的脑袋快速爆炸.

StateT Registers (StateT Memory (State Output)) a = 
StateT (registers -> (StateT Memory (State Output)) (a,registers))

StateT Registers (StateT Memory (State Output)) a = 
StateT (registers -> (Memory -> (Output -> (((a,Registers),Memory),Output))))
Run Code Online (Sandbox Code Playgroud)

我还没有进入FEcycle计数器!

问题:

  1. 我是在正确的轨道上吗?
  2. 看到我现在正在推出monad变形金刚,是否有可能停止将"运行输出"视为状态并将其移至IO monad?这将是非常棒的,而不是坚持它,我可以打印它.
  3. 我应该将状态分成多少层?我可以看到两个不同的层,但它们彼此紧密相关(存储器和寄存器都取决于存储器和寄存器的状态).我应该将它们作为一个单独的状态保存在一起,还是将它们分开并堆叠起来?哪种方法会产生最易读的代码?

monads state haskell state-monad monad-transformers

6
推荐指数
1
解决办法
427
查看次数

广义Newtype导出

Haskell可以MonadState sT1下面派生实例,但不是在T2其中是非常相似的类型.我应该以哪种方式修改代码,T2以便MonadState s可以自动派生实例?

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Control.Monad.Reader
import Control.Monad.State

newtype T1 r s a = 
  T1 { runT1 :: ReaderT r (State s) a }
  deriving (Monad, MonadReader r, MonadState s)

newtype T2 r s a = 
  T2 { runT2 :: StateT r (State s) a }
  deriving (Monad, MonadState r, MonadState s)
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad deriving newtype

6
推荐指数
1
解决办法
2413
查看次数

纯函数随机数发生器 - 状态monad

" Scala中功能编程 "一书演示了如下的纯函数随机数生成器的示例

trait RNG {
    def nextInt: (Int, RNG)
}

object RNG {
    def simple(seed: Long): RNG = new RNG {
        def nextInt = {
            val seed2 = (seed*0x5DEECE66DL + 0xBL) &
                        ((1L << 48) - 1)
            ((seed2 >>> 16).asInstanceOf[Int],
             simple(seed2))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法看起来像

val (randomNumber,nextState) = rng.nextInt
Run Code Online (Sandbox Code Playgroud)

我确实得到了它是纯函数的部分,因为它返回下一个状态并将其留在API客户端上,以便nextInt在下次需要随机数时使用它来调用但我不明白的是' 第一个随机怎么样生成数字,因为我们必须seed至少提供一次.

如果有另一个功能提升seed得到RNG?如果是这样,那么我们如何期望这个API的客户端知道它(因为在非功能实现中用户只是调用nextInt并且状态由API维护)

有人可以给出Scala中纯函数随机数生成器的完整示例,并且可能将它与状态Monad关联起来.

monads functional-programming scala state-monad

6
推荐指数
2
解决办法
2478
查看次数

什么是在Haskell中模拟有状态闭包的正确方法

上下文:我需要编写一个主要是无状态的编译器,它将VM字节码转换为机器码.大多数VM命令都可以使用纯函数进行无状态转换,如下所示:

compilePop = ["mov ax, @sp", "dec ax", "mov @sp, ax"]

compile :: VM_COMMAND -> [String]
compile STACK_POP = compilePop 

-- compile whole program
compileAll :: [VM_COMMAND] -> [String]
compileAll = flatMap compile
Run Code Online (Sandbox Code Playgroud)

但是有些命令需要插入标签,每次调用都应该是不同的.

我理解如何使用整个编译器的状态对象"global"来执行此操作:

compileGt n = [label ++ ":", "cmp ax,bx", "jgt " ++ label]
                where label = "cmp" ++ show n

compile :: Int -> COMPILER_STATE -> VM_COMMAND -> (COMPILER_STATE, [String])
-- here state currently contains only single integer, but it will grow larger
compile lcnt STACK_POP …
Run Code Online (Sandbox Code Playgroud)

closures haskell state-monad

6
推荐指数
1
解决办法
235
查看次数

在MonadState中中断冗长的纯计算

我无法掌握在SIGINT信号上中断冗长的纯计算的正确方法.

在下面的简单示例中,我有slowFib一个模拟冗长计算的函数.当它在IOmonad中运行时,我可以用Cc终止它(使用异步生成worker).

但是,当我将计算放在MonadState, MonadIO堆栈中时,它不再起作用......另一方面,threadDelay在同一堆栈中的简单仍然可以终止.

代码如下:

{-# LANGUAGE FlexibleContexts #-}
module Main where

import Data.Monoid

import Control.DeepSeq
import Control.Concurrent
import Control.Concurrent.Async

import Control.Monad.State
-- import Control.Monad.State.Strict

import System.Posix.Signals

slowFib :: Integer -> Integer
slowFib 0 = 0
slowFib 1 = 1
slowFib n = slowFib (n - 2 ) + slowFib (n - 1)

data St = St { x :: Integer } deriving (Show)

stateFib :: (MonadState St m, MonadIO m) => …
Run Code Online (Sandbox Code Playgroud)

concurrency haskell signals state-monad monad-transformers

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

用于在地图上进行插入和总查找的Monad转换器?

我有一个计算,我在其中将值插入Map,然后再次查找它们。我知道我从来没有在插入密钥之前使用过密钥,但是(!)无论如何随意使用都会使我感到紧张。我正在寻找一种获取总查询功能的方法,该方法不会返回Maybe,并且类型系统可以防止我意外滥用。

我的第一个想法是制作一个类似于的monad转换器StateT,其中状态为a Map,并且在monad中有用于插入和查找的特殊功能。插入函数返回一个新类型Receipt s k,其中sSTmonad 样式的幻像索引类型,并且k是键的类型,而查找函数则使用a Receipt而不是裸键。通过隐藏Receipt构造函数并使用类似于的量化运行函数runST,这应确保查找仅在插入同一映射后发生。(完整代码如下。)

但是我担心我已经重新发明了轮子,或者担心有另外一种获取安全的总地图查找的方法。在某个地方的公共包装中是否存在针对此问题的任何现有技术?

{-# LANGUAGE DeriveFunctor, LambdaCase, RankNTypes #-}

module KeyedStateT (KeyedStateT, Receipt, insert, lookup, receiptToKey, runKeyedStateT)
where

import Prelude hiding (lookup)
import Control.Arrow ((&&&))
import Control.Monad (ap, (>=>))
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe (fromJust)

newtype KeyedStateT s k v m a = KeyedStateT (Map k v -> …
Run Code Online (Sandbox Code Playgroud)

dictionary haskell state-monad monad-transformers st-monad

6
推荐指数
1
解决办法
137
查看次数

当你的代码没有它并不难看时,使用 Monad 有意义吗?

我有一个递归函数,它接收一个包含多个字段的数据对象,例如:

data MyState = {
  first  :: Int,
  second :: String,
  third  :: Bool,
  ... 
}

type Result = Int
Run Code Online (Sandbox Code Playgroud)

这个递归函数在执行期间改变它并将它传递给自己以备下次执行。它看起来如下:

-- This is a pseudocode, just to give an idea about the workflow. 
process :: MyState -> Result
process st = go st
   where go st | first == 1 = (go . changeFunc1) st
               | first == 2 = (go . changeFunc2) st
               | otherwise  = generateResult st

changeFunc1 :: MyState -> MyState
changeFunc1 st | third st …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad

6
推荐指数
0
解决办法
140
查看次数

将 State monad 与任何类型的错误传播相结合

我对 Haskell 相当陌生。我试图通过将任何一个视为 monad 来将 State monad 与错误传播结合起来。我想以不需要显式处理状态或错误的方式递归抽象语法树(例如,用于为语句和表达式编写解释器)。我的印象是,最简单的方法是使用 ExceptT monad 转换器。这是我编译的示例代码:

import Control.Monad.Except
import Control.Monad.State
import qualified Data.Map.Strict as M

-- simple expression language supporting crude let bindings
data Exp = Lit Int | Var String
         | Add (Exp, Exp) | Let (String, Exp, Exp) deriving Show

okExp =  -- let x = 2 in let y = x + 3 in x + y -- evaluate to 7
    Let ("x", Lit 2,
             Let ("y", Add (Var "x", Lit 3), …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad monad-transformers either

6
推荐指数
1
解决办法
367
查看次数

索引单子的高阶编码是如何工作的?

定义索引 monad a la Atkey的常用方法是:

class IxMonad m where
  ireturn :: a -> m i i a
  ibind   :: m i j a -> (a -> m j k b) -> m i k b
Run Code Online (Sandbox Code Playgroud)

另一种方法可以在McBride的工作中找到(他也在这里讨论过):

type f :-> g = forall i. f i -> g i

class MonadIx (m :: (state -> *) -> (state -> *)) where
  returnIx    :: f :-> m f
  flipBindIx  :: (f :-> m g) -> (m f …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad

6
推荐指数
1
解决办法
128
查看次数