这是我试图找出的状态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提示符上看到getState
和putState count
的操作。
State Monad材料的任何教程或链接都会很好。
答案 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
是(修改的)状态。