标签: state-monad

每次调用函数时生成顺序或随机值

我需要让每个实例 Sphere获得一个唯一标识符,以便没有两个Spheres 相等。我不会提前知道需要制作多少个球体,因此需要一次制作一个,但仍会增加标识符。

我尝试过的大多数解决方案都有这个问题,我最终得到了一个IO a并需要unsafePerformIO来获得价值。

这段代码很接近,但结果identifier总是一样的:

module Shape ( Sphere (..)
             , sphere
             , newID
             ) where

import System.Random
import System.IO.Unsafe (unsafePerformIO)

data Sphere = Sphere { identifier :: Int
                     } deriving (Show, Eq)

sphere :: Sphere
sphere = Sphere { identifier = newID }

newID :: Int
newID = unsafePerformIO (randomRIO (1, maxBound :: Int))
Run Code Online (Sandbox Code Playgroud)

这也可以工作,并且在 REPL 中工作得很好,但是当我把它放在一个函数中时,它只在第一次返回一个新值,然后返回相同的值。

import Data.Unique
sphere = Sphere { identifier = (hashUnique $ unsafePerformIO newUnique) …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

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

在 Haskell 的 do 块中使用 let 中的状态

我有以下数据结构和功能:

data BTree a = BLeaf | BNode (BTree a) a (BTree a) deriving (Show, Eq)
freshNodesS :: BTree String -> State [String] (BTree String)
freshNodesS BLeaf = return BLeaf
freshNodesS (BNode l m r) = do  l' <- freshNodesS l
                                let m' = getFresh m s
                                let s' = m : s
                                r' <- freshNodesS r s'
                                return (BNode l' m' r')
Run Code Online (Sandbox Code Playgroud)

有一个问题,我实际上想使用freshNodesS l应该给出输出的状态(BTree String, [String]),但是在我不能使用的 do 块中(l', s) <- freshNodesS l,我看到的唯一选择是将所有内容都放在 lambda …

haskell state-monad

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

理解 Haskell 中的 RWST

我研究了这个,试图理解几个转换器单子如何相互作用,特别是更好地理解单子lift并与单子堆叠

对于这里找到的 RWST monad (我认为这是最好的文档),它是一个堆叠的 monad,其中 Reader、Writer、State 都是一个 Monadic 层(并且按照堆叠顺序)。或者说应该如何理解呢?当我查看定义时,runRWST :: r -> s -> m (a, s, w)我将其理解为将读取器环境作为状态环境并将任何单子包装在 的m返回值周围RWS。这也意味着这个monad中只存在两层monad。即外部 monadm和包含多个 monad 的元组。

这反过来也意味着您只能使用lift一次。将读取器状态单子中的值提升到外部单子中。

从这个意义上说get, 和ask只是应用两个内部单子之一的两个函数。对于最后一点,我仍然不确定我是否理解为什么即使阅读了这篇 stackoverflow 帖子,您仍然需要一个reader和一个state -monad 。我猜读者只对只读有意义,但如果不希望这样,可以在两个单独的状态单子周围使用变压器单子吗?

一个例子:

这些评论让我有理由思考并使以下内容更加明确......以下类型定义的内部单子和外部单子是什么?它本身是RWST一个包裹着(因此是外部单子)Either String(内部单子)的单子吗?

type MyRWST a = RWST
                 (String -> Either String …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming state-monad monad-transformers

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

使用State-Monad在Haskell中的类集方法

我最近看过Haskell的Monad - State.我已经能够创建与Monad一起运行的函数,但我正在尝试将行为封装到类中,基本上我正在尝试在Haskell中复制这样的事情:

class A {
  public:
  int x;
  void setX(int newX) {
      x = newX;
  }
  void getX() {
      return x;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果有人能帮助我,我将非常感激.谢谢!

haskell translate referential-transparency state-monad data-structures

0
推荐指数
1
解决办法
962
查看次数

来自Haskell的State Monad的ID

可能重复:
在Haskell中创建唯一标签

我有一个数据类型Person和一些输入数据,我将从中创建人员.

我想让每个人都有自己的ID(假设整数[0 ..]).我可以通过递归来做到这一点,但是因为我在Haskell中这样做,所以我想了解monad.我想,State Monad可能是这项工作的最佳人选.

问题是,我并不是很了解很多东西:当我在monad中时(什么功能可以使用内部),我如何将它们连接在一起,如何使'tick'功能提前等等. .

所以我现在坚持这个:滴答功能可能有效,但我不知道如何使用它; 以及如何相继获得人才建设的价值.

import Control.Monad.State

data Person = Person {
  id   :: Int,
  name :: String
} deriving Show

type MyState = Int
startState = 0

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

names = ["Adam","Barney","Charlie"]

-- ??? -> persons = [Person 0 "Adam", Person 1 "Barney", Person 2 "Charlie"]

main = do
  print $ evalState tick startState
  -- ???
Run Code Online (Sandbox Code Playgroud)

编辑:使用Data.Unique或Data.Unique.Id会更容易吗?如何在我的情况下使用它?

monads haskell uniqueidentifier state-monad

0
推荐指数
1
解决办法
905
查看次数

使用状态monad返回值

我是Monads和Haskell的新手,并试图了解如何在使用它们时返回值.我的代码如下所示:

foo :: A -> B
foo a = do  b <- fooC a (C 0)
            -- want to return just (B "b")

fooC :: A -> C -> State MyState B
fooC a c = return (B "b")
Run Code Online (Sandbox Code Playgroud)

我试过用snd (snd b),但显然State MyState B不是一个元组?如何返回所需的值(B "b")

编辑:考虑到丹尼尔的建议,重写如下:

data MyState = MyState String
data C = C Int
foo :: String -> String
-- want to return just "b"
foo a = evalState (fooC a) …
Run Code Online (Sandbox Code Playgroud)

monads haskell state-monad

0
推荐指数
1
解决办法
541
查看次数

如何将STArray转换为Haskell中的List?

有功能可以做功能arrayToList吗:

import Data.Array.ST
import Control.Monad.ST

genArray :: ST s [Int]
genArray = do
   a <- new Array (0, 99) 0 :: ST s (STArray s Int Int)
   writeArray a 0 1
   {- ... write something to the array ... -}
   return arrayToList(a)
Run Code Online (Sandbox Code Playgroud)

如果没有,怎么写一个?

monads haskell state-monad

0
推荐指数
1
解决办法
518
查看次数

如何改善滚动总和实施?

如何改进以下滚动总和实施?

type Buffer  = State BufferState (Maybe Double)
type BufferState = ( [Double] , Int, Int )

-- circular buffer    
buff :: Double -> Buffer 
buff newVal = do
  ( list, ptr, len) <- get
  -- if the list is not full yet just accumulate the new value
  if length list < len
    then do
      put ( newVal : list , ptr, len)
      return Nothing
    else do
      let nptr = (ptr - 1) `mod` len
          (as,(v:bs)) = splitAt ptr list …
Run Code Online (Sandbox Code Playgroud)

haskell state-monad

0
推荐指数
1
解决办法
236
查看次数

创建`State [Int] Int`

通过Learn You a Haskell阅读,我正在尝试构建一个Stack [Int] Int:

ghci>import Control.Monad.State

ghci> let stack = state ([1,2,3]) (1) :: State [Int] Int

<interactive>:58:20:
    Couldn't match expected type `s0 -> (State [Int] Int, s0)'
                with actual type `[t0]'
    In the first argument of `state', namely `([1, 2, 3])'
    In the expression: state ([1, 2, 3]) (1) :: State [Int] Int
    In an equation for `stack':
        stack = state ([1, 2, 3]) (1) :: State [Int] Int
Run Code Online (Sandbox Code Playgroud)

我该如何创建Stack [Int] Int …

haskell state-monad

0
推荐指数
1
解决办法
113
查看次数

结果状态是提供的参数的状态,值是单位

23.8.2在haskell书中练习要求我构建如下状态:

put' :: s -> State s ()
put' s = undefined
-- should act like:
-- Prelude> runState (put "blah") "woot"
-- ((),"blah")
Run Code Online (Sandbox Code Playgroud)

我得到的唯一一个类型的实现是

import Control.Monad.Trans.State -- Not sure this is the right import
put' :: s -> State s ()
put' s = state $ \s -> ((), s)
Run Code Online (Sandbox Code Playgroud)

但这会在参数中返回状态runState,而不是put':

?> runState (put' "blah") "woot"
((),"woot")
Run Code Online (Sandbox Code Playgroud)

我需要修复什么haskell杂技?看不出我怎么能访问"blah".

haskell state-monad

-2
推荐指数
1
解决办法
55
查看次数