对于Haskell来说,我是个新手,我现在正试图通过为一种简单的命令式玩具语言编写一个解释器来提高我的技能。
这种语言中的一个表达式是input,它从标准输入中读取一个整数。但是,当我将这个表达式的值赋值给一个变量,然后在以后使用这个变量时,我似乎并不认为我实际上存储了读取值的计算,而不是读值本身。这意味着,例如声明
x = input;
y = x + x;
将导致解释器调用输入过程三次而不是一次。
在计算器模块内部,我使用一个Map来存储变量的值。因为我需要处理IO,所以它被包装在一个IO monad中,在下面的最小示例中是永久化的:
import qualified Data.Map a
我不知道我怎样才能有条件地改变哈斯克尔州的Monad州。假设,我有一堆关于州立Monad的书。
import Control.Monad.State
push :: Int -> State [Int] ()
push x = state $ \xs -> ((), x : xs)
pop :: State [Int] Int
pop = state $ \(x : xs) -> (x, xs)
有了这个,我想写一个函数来改变它。
someFunc :: Bool -> Int -> State [Int] ()
someFunc b x = do
le
我有一个在IntMap上操作的算法,我觉得最好用必要的方式来表达。也就是说,我想说的是:
查找映射中的值X。如果与标准匹配,则从map.循环中删除该值,直到映射中不再存在值。
将其表示为两行递归非常简单,但是实际的算法要复杂一些,包括几个查找和删除,所以我希望能够用do符号来表示它。
是否有一个标准的" state "-like monad,其中的状态由Data.Map或Data.IntMap表示,我可以这样做:
do
insert 5 20
(ma, mv) <- lookup 4
case mv of
Just v -> delete (fr
好的,所以我用java实现了state monad。然而,我似乎不能让泛型正常工作。我有下面的代码,并试图避免指示的情况。
public interface Monad<M, A>
{
<B, R extends Monad<M, B>> R bind(Function<? super A, R> p_function);
}
public class State<S, A> implements Monad<State<S, ?>, A>
{
private Function<S,
我想定义两个dom元素之间的关系(在我的特殊情况下,在to节点之间绘制直线),方法是先单击第一个,然后再单击第二个。以下是我的方法。我不认为它特别优雅或干净。有没有更好的方法来做这件事?
$(function() {
var State = {
initialClick: false, // tracks clicks status for drawing lines
initialID: undefined // remember data gotten from the first click
};
...
$map.on('c
我试图为Monad和MonadState实例提供计算(>>=), return, get和put操作数量的State'实例。
data Counts = Counts { binds :: Int
, returns :: Int
, gets :: Int
, puts :: Int
}
newtype State' s a = State' { runState' :: (s, Counts)
这个可能是一个愚蠢的,但是,看看()
type State<'s,'a> = State of ('s -> 'a * 's)
type StateBuilder<'s>() =
member x.Return v : State<'s,_> = State(fun s -> v,s)
member x.Bind(State v, f) : State<'s,_> =
State(fun s ->
let (a,s) = v s
由于数据/ monad模块的do表示法在结构上运行,我如何定义作为函数的monad类型,例如解析器?
我已经习惯了OCaml,我的monad大概有以下签名:
module type Parser = sig
type state = string * int
type 'a t = state -> (('a * state), string) Result.t
val return: 'a -> 'a t
val bind: 'a t -> ('a -> 'b t) -> 'b t
我在多线程环境中有一个有状态bean,它将其状态保持在一个映射中。现在,我需要一种方法,在一个原子操作中替换映射的所有值。
public final class StatefulBean {
private final Map<String, String> state = new ConcurrentSkipListMap<>();
public StatefulBean() {
//Initial state
this.state.put("a", "a1");
th
给定一个mtl单栈(例如,ExceptT String (WriterT String (State s a)) ),我如何在不需要打开外部单块的情况下评估内部状态单块?
have :: ExceptT String (WriterT String (State s)) a
f :: State s a -> a
want :: ExceptT String (WriterT String Identity) a
我可以调用runExceptT,然后再调用runWriterT,然后重新打包结果,但这似乎是实现这一目标的错误方法。
据我所知,类似于fmap或类似的东西无法工作,因
我想要定义一个函数,它需要一个Int,根据数字(x)在控制台中打印一个错误,然后用Nothing更新State。
如何在一个函数中加入这些命令?
我得到的是:
type Env = [(Variable,Int)]
newtype StateError a = StateError { runStateError :: Env -> Maybe (a, Env) }
class Monad m => MonadError m where
throw :: Monad m => a -> m a
instance MonadError State
注意:这只是一个练习,我正在尝试理解事物是如何工作的。
我正在尝试让在Haskell中做这样的事情成为可能:
f :: Integer -> Integer
f n = def $ do
i <- var n
while i (>0) $ do
i -= lit 1
return i
-- for now, my program returns n
下面是我的程序。在这一点上,我不明白为什么它不能工作,但由于某些原因,变量没有改变。
import Control.Monad.State
data Lit a = Lit a
typ
例如,ParsecT在其定义中有多个类型变量。
newtype ParsecT s u m a
= ParsecT {unParser :: forall b .
State s u
-> (a -> State s u -> ParseError -> m b)
-> (ParseError -> m b)
-> (a -> State s u -> ParseError -
我正在写一个编程语言解释器。
我需要正确的代码习惯用法来计算表达式序列以获得它们的值序列,并在求值发生时将状态从一个计算器传播到下一个计算器。我想要一个函数式编程的习惯用法。
这不是一个折叠,因为结果就像一张地图。这不是一张地图,因为它是国家道具。
我所拥有的是这段代码,我正在使用它来试图弄清楚这一点。先忍受几行测试设备:
// test rig
class MonadLearning extends JUnit3Suite {
val d = List("1", "2", "3") // some expressions to evalu
Data.Vector.Mutable似乎需要PrimMonad在ST s和IO monads中的一个实例。
类型化定义为--
-- | Class of primitive state-transformer monads
class Monad m => PrimMonad m where
-- | State token type
type PrimState m
-- | Execute a primitive operation
primitive :: (State# (PrimState m) -> (# State# (PrimState m),
我有一个简单的代码,它读取一个字符串并无限期地打印它。
main :: IO ()
main = getLine >>= putStrLn >> main
现在,如果行为“退出”或“退出”,则希望在getLine调用之后退出。
我的尝试:
main :: IO ()
main = do
line <- getLine
if line == "exit" || line == "quit"
then return ()
else putStrLn line >> main
在我看来不是惯用的。有更好的办法吗
我正在阅读,但我无法理解它,因为堆栈示例无法编译。在本指南中,他使用了以下代码:
import Control.Monad.State
type Stack = [Int]
pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)
push :: Int -> State Stack ()
push a = State $ \xs -> ((),a:xs)
虽然我知道它应该做什么,但它不会编译。我不知道为什么。错误消息为:
Stack.hs:6:7: Not in scope: data constr
我试图在OCaml中实现状态monad (作为练习)。我的实现如下所示:
module type MONAD_BUILDER =
sig
type 'a t
val return : 'a -> 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t
end;;
module MonadBuilder = functor (M: MONAD_BUILDER) ->
struct
let ( >>= ) = M.bind
let return
class Monad m => MonadState s m | m -> s where
-- | Return the state from the internals of the monad.
get :: m s
get = state (\s -> (s, s))
-- | Replace the state inside the monad.
put :: s -> m ()
put s = state (\_ -> ((), s))
-- | Embed a simple state a
使用以下代码:
(lazy_test.hs)
-- Testing lazy evaluation of monadically constructed lists, using State.
import Control.Monad.State
nMax = 5
foo :: Int -> State [Int] Bool
foo n = do
modify $ \st -> n : st
return (n `mod` 2 == 1)
main :: IO ()
main = do
let ress = for [0..nMax] $ \n -> run
我试图通过Euler项目来教自己Haskell (再一次)。问题14 ()正在乞求动态编程,从历史上看,我一直强烈反对monad (因为屡次没有学会使用它们来使生活变得更容易而不是更困难),所以我试图咬紧牙关,用State monad回忆录我的代码.情况不太好。我想说清楚,我已经用简单/缓慢的方式解决了这个问题,此时我正在努力学习一些东西(即不是我想要的)。
到目前为止我的代码是:
collatzMemoCheck :: Int -> State (Map Int Int) Int
collatzMemoCheck n = state $ \s -> maybe (let (a,
我正在读一个yaml,结果是一个可能: main :: IO ()
main =
do
justConfig <- decodeFile "config.yaml" :: IO (Maybe Config)
case justConfig of
Just config -> initState $ config
Nothing -> initState $ (Map.fromList [("hi", "bye")]) 如何从以下位置提取initState的结果: do
编辑
这是的后续问题。
给出了chainRec型
chainRec :: ChainRec m => ((a -> c, b -> c, a) -> m c, a) -> m b
通常,chainRec是与蹦床一起实现的,这样可以在单块内实现堆栈安全递归。然而,如果我们放弃蹦床,我们可以为正常的功能实现chainRec的类型如下:
const chainRec = f => x => join(f(chainRec(f), of, x));
接下来,我想将它应用于递归操作:
const map = f => g => x =>
我只是把我的头集中在单子上(至少我认为我是这样做的),更具体地说,是州立单子,有些人比我聪明得多,所以我很可能会回答这个问题。
无论如何,状态monad通常是用一个M<'a>实现的,如下所示(F#):
type State<'a, 'state> = State of ('state -> 'a * 'state)
现在我的问题是:你为什么不能在这里使用元组?另外,MonadA<'a, 'b>和MonadB<'a, 'b>之间可能存在歧义,这两者都将成为等价的(
我一直在玩一些简单的二进制编码,它似乎在大部分时间都是正确的,直到我添加了状态monad。我们的计划是使用状态来保存我到目前为止已经写到字节串的查找表,然后将偏移写到以前的字符串实例中,而不是重复它们。
我检查并运行了所有的类型,但是我注意到它只是写在链中的最后指令。我改变了使用Control.Monad.State.Strict,但这并没有什么区别,所以我怀疑我在其他地方犯了一个根本错误,但我不知道在哪里--我已经将代码缩减到了基本功能。还有,有没有一种更惯用的方法来做这件事?
{-# LANGUAGE OverloadedStrings #-}
import Con