我想编写一个函数来计算平均值,使用状态Monad in haskell这是我写的代码
import Control.Monad.State
type MyState = (Double,Double)
media s (a,n)= ((a*n+s)/(n+1),n+1)
getAverage:: Double ->State MyState s1-> Double
getAverage s c=get >>= \s0 -> let (x,s1) =media s s0
in put s1 >> return x
Run Code Online (Sandbox Code Playgroud)
我在GHCI编译时遇到这个错误,我坚持在那里你可以帮我理解什么是错的,提前谢谢你
我正在尝试并行执行计算,并将结果写入STArray.我认为这段代码显示了我正在尝试做的事情.但是,我收到了编译错误.
import Control.Monad
import Control.Monad.ST
import Control.Parallel
import Data.Array.ST
main = do
arr <- newArray ((0,0), (5,5)) 0 :: ST s (STArray s (Int, Int) Int)
runSTArray $ do
par (writeArray arr (1,1) 17) (writeArray arr (2,2) 23)
return arr
print arr
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
http://hackage.haskell.org/packages/archive/mtl/1.1.0.2/doc/html/src/Control-Monad-State-Lazy.html
instance (Monad m) => MonadState s (StateT s m) where
get = StateT $ \s -> return (s, s)
put s = StateT $ \_ -> return ((), s)
Run Code Online (Sandbox Code Playgroud)
()在put的定义中做了什么?
我试图创建一些看起来很像State monad的东西,但是它还带有一个谓词列表和相应的状态转换函数.我想象的计算的基本步骤如下:
Foo (state, [(pred, t)]) >>= f.适用f于s,产生s'.然后将每个谓词应用于s'.对于匹配的每个谓词,将关联的转换函数按顺序应用于状态.例如,假设[(p1, t1), (p2, t2), (p3, t3)],f和s.如果在f s收益率之后s',p1 s'并且p3 s'两者都返回True,那么你将执行t1 s'屈服s'',然后执行t3 s''屈服s''',即计算的结果.
这里有很多移动部件,我觉得正确的方法是在StateT变换器或State monad之上构建它,但是我无法弄清楚从哪里开始.
我觉得好像这不是很清楚.任何澄清会使这个更清楚,非常感谢.
考虑以下Haskell代码:
import Control.Monad.State
test :: Int -> [(Int, Int)]
test = runStateT $ do
a <- lift [1..10]
modify (+a)
return a
main = print . test $ 10
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
[(1,11),(2,12),(3,13),(4,14),(5,15),(6,16),(7,17),(8,18),(9,19),(10,20)]
Run Code Online (Sandbox Code Playgroud)
但是我想生成以下输出:
[(1,11),(2,13),(3,16),(4,20),(5,25),(6,31),(7,38),(8,46),(9,55),(10,65)]
Run Code Online (Sandbox Code Playgroud)
使用像JavaScript这样的不纯语言很容易做到这一点:
function test(state) {
var result = [];
for (var a = 1; a <= 10; a++) {
result.push([a, state += a]);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
你如何在Haskell做同样的事情?
monads haskell non-deterministic state-monad monad-transformers
在Haskell/Understanding monads/State中有一个代码片段:
type GeneratorState = State StdGen
rollDie :: GeneratorState Int
rollDie = do generator <- get
let (value, newGenerator) = randomR (1,6) generator
put newGenerator
return value
Run Code Online (Sandbox Code Playgroud)
关于<-上面第三行中的符号,有一个解释:
我们<-与get一起取出伪随机生成器.获得覆盖一元值(a中m a)与状态,结合发电机的状态.(如果有疑问,请回忆一下get和>>=above 的定义).
我不明白:(1)generator对应于定义的第一个类型参数State?(2)为什么generator只是两个参数中的一个State,而不是两个?当然,从上下文来看,答案是显而易见的,但我不知道具体的规则<-.
据我所知,在评估时evalState rollDie (mkStdGen 600),get将被替换为State (mkStdGen 0) (mkStdGen 0),并且,根据RWH的描述" <-拉出monad的东西",这里的东西不是(mkStdGen 0) (mkStdGen 0)?
我正在学习State Monad并且无法理解Wiki中的一个例子(http://en.wikibooks.org/wiki/Haskell/Understanding_monads/State)
rollDie :: GeneratorState Int
rollDie = do generator <- get
let (value, newGenerator) = randomR (1,6) generator
put newGenerator
return value
Run Code Online (Sandbox Code Playgroud)
在put有定义
put newState = State $ \_ -> ((), newState)
Run Code Online (Sandbox Code Playgroud)
它似乎put只是创造了一个新的State,这条线的实际用途是什么?如果要使用该值可能应该使用<-提取,而如果state要再使用则应该使用get.如果删除这一行(或者我错过了什么?)没有区别,那么,这条线的真正含义是什么?
我想通过以下函数传递State monad:
e1 :: Int -> (Bool, Int)
e1 el
| el > 100 = (True, el)
| otherwise = (False, 0)
e2 :: Int -> (Bool, Int)
e2 el
| el > 200 = (True, el)
| otherwise = (False, 0)
e3 :: Int -> (Bool, Int)
e3 el
| el > 300 = (True, el)
| otherwise == (False, 0)
implementor :: State Bool Int
implementor = state e1 ...
main = do
print $ runState implementor 10 …Run Code Online (Sandbox Code Playgroud) 我有两个或更多独立状态要在一个Haskell应用程序中跟踪.
我正在使用声明两个新类型
type MonadTuple m = MonadState (Int, Int) m
type MonadBool m = MonadState Bool m
Run Code Online (Sandbox Code Playgroud)
monad变换器堆栈声明为
type Stack = StateT (Int, Int) (StateT Bool IO) ()
Run Code Online (Sandbox Code Playgroud)
我打算像这样使用堆栈
ret :: Stack
ret = apply
apply :: (MonadTuple m, MonadBool m) => m ()
apply = undefined
Run Code Online (Sandbox Code Playgroud)
该编译器是不高兴,因为它不能匹配Bool与(Int, Int)试图检查时Stack符合MonadBool.
我知道在StateT中组合多个状态时给出的解决方案.除了箭头或带镜头的全局状态之外,还有其他更简单的解决方案吗?
附录:完整的代码块是
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.State.Class
import Control.Monad.State.Lazy
type MonadTuple m …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用State monad进行一些计算,同时还要对其进行更改。我已经实现的情况下Applicative,Monad和Functor以及get和put,modify等我不明白的脱糖do块。您如何同时提供状态和状态转换器?
实用程序
get::State s s
get=State $ \s ->(s,s)
put::s->State s ()
put x=State $ \_ -> ((),x)
modify::(s->s)->State s ()
modify f=get>>= \x -> put (f x)
evalState::State s a->s->a
evalState act =fst . run act
execState::State s a->s->s
execState act=snd.run act
Run Code Online (Sandbox Code Playgroud)
码
module Env where
import State
import System.Directory
import Control.Monad
data Env=Env{
envName::String,
fileNames::[String]
}
instance Show Env where
show Env{envName=x,fileNames=xs} = …Run Code Online (Sandbox Code Playgroud)