创建/处理Monad.State的列表?

时间:2011-11-10 21:15:01

标签: haskell state

我正处于学习haskell的过程中,我确信存在以下问题的优雅解决方案。 给定函数f,返回有状态计算

f :: (Num a) => a -> a -> State [a] a
f x y = modify ((2*x):) >> return (x+y)   -- state and value are modified based on the passed values

我正在寻找以递归方式从给定的一个State生成多个g :: (Num a) => [a] -> (a, [a]) -> [(a,[a])] g [] _ = [] g (x:xs) aa@(a,b) = (new : next) where new = runState (f x a) b -- here the old value a is required! next = g xs aa 的最简洁方法(如下所示)。我想出的一个解决方案是以下

g :: [a] -> [State [a] a] 

但我觉得像

g x (y, s)

应该可行且更干净吗?我没有成功尝试这个并从StateT得到我无法弄清楚的错误。

谢谢!

背景:代码是我正在编写的图形生成器的一部分的简化,其中状态是当前的邻接向量。对于每个节点,可以创建多个边缘,因此需要多个状态来表示不同的(部分)图形。

编辑 :(尝试)上述函数x中单词的描述:

对于给定的值列表y,单个值s和状态x_i,为x中的每个(y,s)递归计算一个新值并从状态计算f x_i y给出的 g [1,2,3] (4,[2,3,4]) == [(5,[10,2,3,4]),(6,[12,2,3,4]),(7,[14,2,3,4])] 状态,并将结果作为列表返回。

编辑2 :示例输出:

{{1}}

1 个答案:

答案 0 :(得分:3)

以下是对g函数的一些迭代更改。我希望这是你想要的,因为我不确定我完全理解你想要达到的目标:

你原来的g:

g :: Num a => [a] -> a -> [a] -> [(a,[a])]
g [] _ _ = []
g (x:xs) a b = new : next
  where
    new = runState (f (h x a)) b   -- here the old value a is required!
    next = g xs a b

点免费:

g1 :: Num a => [a] -> a -> [a] -> [(a,[a])]
g1 xs a b = map (($ b) . runState . f . (`h` a)) $ xs

翻转ETA还原性:

g2 :: Num a => [a] -> a -> [a] -> [(a,[a])]
g2 b a = map (($ b) . runState . f . (`h` a))

没有($ b) . runState应用程序(因为我们不应用状态计算,所以不需要额外的[a]参数):

g3 :: Num a => a -> [a] -> [State [a] a]
g3 a = map (f . (`h` a))

那里的地图也可以写成:

map f . map (`h` a)

然后你可以拿

 map (\`h\` a)

在其他地方分开。

这为您提供了类似于g所需类型的东西,当然也改变了语义(因为该类型仍未应用于输入状态)