我正在尝试http://www.haskell.org/haskellwiki/State_Monad#Complete_and_Concrete_Example_1
给出的示例这使得解决方案的可解决性超出了我的理解范围。这是我尝试过但我得到的编译错误如下:
Couldn't match expected type `GameValue -> StateT GameState Data.Functor.Identity.Identity b0'
with actual type `State GameState GameValue'
In the second argument of `(>>=)', namely `g2'
In the expression: g1 >>= g2
In an equation for `g3': g3 = g1 >>= g2
Failed, modules loaded: none.
以下是代码:参见结束行
module StateGame where
import Control.Monad.State
type GameValue = Int
type GameState = (Bool, Int)
-- suppose I want to play one game after the other
g1 = playGame "abcaaacbbcabbab"
g2 = playGame "abcaaacbbcabb"
g3 = g1 >>= g2
m2 = print $ evalState g3 startState
playGame :: String -> State GameState GameValue
playGame [] = do
(_, score) <- get
return score
playGame (x:xs) = do
(on, score) <- get
case x of
'a' | on -> put (on, score + 1)
'b' | on -> put (on, score - 1)
'c' -> put (not on, score)
_ -> put (on, score)
playGame xs
startState = (False, 0)
main str = print $ evalState (playGame str) startState
答案 0 :(得分:2)
g1 = playGame "abcaaacbbcabbab"
g2 = playGame "abcaaacbbcabb"
g3 = g1 >>= g2
g1
和g2
都属于State GameState GameValue
类型。但(>>=)
的类型为
(>>=) :: Monad m => m a -> (a -> m b) -> m b
因此它的第二个参数必须是一个函数。如果第一个参数是g1
,则该函数必须具有类型
GameValue -> State GameState b
这是错误消息中的“预期类型”。但g2
有不同的类型,即“实际类型”。
g3
定义中您想要的组合子是(>>) :: Monad m => m a -> m b -> m b
,
g3 = g1 >> g2
答案 1 :(得分:2)
您可以通过两种方式组合两款游戏。第一种选择是在第一场比赛之后运行第二场比赛,从一个新的状态开始。您可以使用以下方式执行此操作:
main = do
print $ evalState g1 startState
print $ evalState g2 startState
或者,您可以在第一场比赛结束时进行第二场比赛。您可以使用以下方式执行此操作:
g3 = do
g1
g2
...这只是语法糖:
g3 = g1 >> g2
...并运行:
main = print $ evalState g3 startState