“实例显示状态”不编译

时间:2011-11-01 13:12:15

标签: haskell monads state-monad

这是我试图找出的状态Monad代码

data State a = State (Int -> (a, Int)) 
instance Monad State where
    return x = State (\c -> (x, c))     
    State m >>= f = State (\c ->
        case m c of { (a, acount) ->
            case f a of State b -> b acount})

getState = State (\c -> (c, c))
putState count = State (\_ -> ((), count))

instance Show State where  -- doesn't work
    show (State a) = show a   -- doesn't work

我正在尝试将State作为Show的实例,以便我可以在ghci提示符上看到getStateputState count的操作。

State Monad材料的任何教程或链接都会很好。

3 个答案:

答案 0 :(得分:5)

这是一个Show实例,可以帮助查看正在发生的事情:

instance Show a => Show (State a) where
  show (State f) = show [show i ++ " => " ++ show (f i) | i <- [0..3]]

然后你可以这样做:

*Main> getState
["0 => (0,0)","1 => (1,1)","2 => (2,2)","3 => (3,3)"]
*Main> putState 1
["0 => ((),1)","1 => ((),1)","2 => ((),1)","3 => ((),1)"]

答案 1 :(得分:5)

在Haskell中,类型类只分类相同的类型。 Monad对类型* -> *进行分类,而Show则对类型*进行分类。您的州类型具有* -> *种类,这就是您的Monad实例没有问题的原因,但 您的Show实例存在问题。 State被称为“类型构造函数”,因为它使用一种类型来生成另一种类型。可以认为它类似于类型级别的函数应用程序。因此,您可以应用特定类型并创建该实例:

instance Show (State Char) where
    show _ = "<< Some State >>"

现在,这不是一个非常有用的实例,尝试像Sjoerd的建议来获得更有意义的Show实例。请注意,他的版本使用带有约束的泛型类型

instance (Show a) => Show (State a) where
    -- blah blah

泛型类型为a,约束为(Show a) =>,换句话说,a本身必须是Show的实例。

答案 2 :(得分:3)

这是对Monad状态的一个很好的(也是我最喜欢的)解释:Learn You A Haskell。 (也是学习Haskell的一个很好的资源)。

您可能已经注意到函数不是Haskell中Show类型类的一部分。由于State基本上只是某些类型函数的newtype包装器,因此您无法创建State的{​​有意义的} Show实例。


这是使用LYAH的State Monad的代码:

import Control.Monad.State -- first, import the state monad

pop :: State Stack Int  
pop = State $ \(x:xs) -> (x,xs)  

push :: Int -> State Stack ()  
push a = State $ \xs -> ((),a:xs)

stackManip :: State Stack Int  
stackManip = do  
    push 3  
    a <- pop  
    pop

以下是来自ghci的代码:

*Main> runState stackManip [1,2,3]
(1,[2,3])

元组的fst是结果,元组的snd是(修改的)状态。