1

我需要在haskell中环绕状态单子,我对此有一些问题。任务是实现一个函数countConcat将字符串与状态 monad 和一个函数extractCC连接起来,它得到这个函数的结果。

所以extractCC ((return 0) >>= countConcat "a" >>= countConcat "b" >>= countConcat "c")会产生 (3,"abc")

据我了解 countConcat 将是一种操纵器函数,而 extractCC 应该包含某种 runState,对吗?

非常感谢任何让我进入正确方向的提示或资源。(我已经浏览过 wiki 和 learnyouahaskell 部分,但仍然觉得这很愚蠢)

4

3 回答 3

5

先试试这个

concat' :: String -> State (Int,String) ()
concat' s = do
  (c,st) <- get
  put (c+1, st ++ s)

你可以运行这个

> runState ( concat' "A" >> concat' "B" >> concat' "C" ) (0,"")
((),(3,"ABC"))

我认为如果您了解 state monad,您可以根据需要修改上面的示例。

于 2013-06-04T14:42:51.487 回答
4

感谢 Satvik,我能够解决问题。这是我的最终解决方案:

newtype State s a = State {runState :: s -> (a,s)}

instance Monad (State s) where  
    return x = State (\s -> (x,s))
    (State h) >>= f = State (\s -> let (a, newState) = h s
                                       (State g)     = f a  
                                   in  g newState)

                      -- Save new state
countConcat :: String -> Int -> State String Int
countConcat s i =do
  st <- get -- get current string
  put ((st ++ s)) -- put conc. string
  return (i+1) -- return new counter


extractCC f =(runState f ("")) --run the function, staring with an empty string


-- Helper from the wiki
put newState = State $ \_ -> ((), newState)
get = State $ \st -> (st, st)

-- extractCC ((return 0) >>= countConcat "a" >>= countConcat "b" >>= countConcat "c")
-- (3,"abc")
于 2013-06-04T15:04:12.647 回答
0

如果您使用first来自 的组合子Control.Arrow,则:

countConcat :: String -> State (String,Int) ()
countConcat s = modify ((<> s) *** (+1))
于 2013-06-04T17:18:30.247 回答