“instance Show State where” doesn't compile

三世轮回 提交于 2019-12-11 00:53:57

问题


This is the State Monad code I am trying to figure out

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

I am trying to make State as instance of Show so that I can see the action of getState and putState count on the ghci prompt.

Any tutorial or link to State Monad material would be nice too.


回答1:


Here's is a Show instance that can help see what's going on:

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

Then you can do:

*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)"]



回答2:


In Haskell, typeclasses classify only types of the same kind. Monad classifies types of kind * -> *, while Show classifies types of kind *. Your State type has kind * -> * which is why there isn't a problem with your Monad instance, but there is a problem with your Show instance. State is called a "type constructor" because it consumes a type in order to produce another type. Think of it sort of like function application at the type level. You can therefore apply a specific type and make instances of that:

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

Now, this isn't a very useful instance, try something like Sjoerd's suggestion to get a more meaningful Show instance. Notice that his version uses a generic type with a constraint.

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

The generic type is a, and the constraint is (Show a) =>, in other words, a itself must be an instance of Show.




回答3:


Here's a great (and personally, my favorite) explanation of the State Monad: Learn You A Haskell. (Also a great resource for learning Haskell in general).

You may have noticed that functions aren't part of the Show typeclass in Haskell. And since State is basically just a newtype wrapper for functions of certain types, you can't make a (meaningful) State instance of Show.


Here's code using the State Monad from LYAH:

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

And here's that code in action from ghci:

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

The fst of the tuple is the result, and the snd of the tuple is the (modified) state.



来源:https://stackoverflow.com/questions/7966956/instance-show-state-where-doesnt-compile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!