2

これは私が理解しようとしている州のモナドコードです

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

ghciプロンプトのアクションgetStateを確認できるように、StateをShowのインスタンスとして作成しようとしています。putState count

チュートリアルやStateMonadの資料へのリンクもいいでしょう。

4

3 に答える 3

5

Haskell では、型クラスは同じ種類の型のみを分類します。Monad は kind の型を* -> *分類し、Show は kind の型を分類します*。State タイプには種類* -> *があるため、インスタンスに問題はありませんが、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

于 2011-11-01T18:12:23.513 に答える
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)"]
于 2011-11-01T13:32:50.637 に答える
3

State Monad のすばらしい (個人的には私のお気に入りの) 説明は、 Learn You A Haskellです。(Haskell 全般を学習するための優れたリソースでもあります)。

Show関数はHaskellの型クラスの一部ではないことに気付いたかもしれません。はState基本的に特定の型の関数の単なるラッパーであるため、(意味のある)のインスタンスをnewtype作成することはできません。StateShow


以下は、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、タプルの は (変更された) 状態です。

于 2011-11-01T13:16:07.923 に答える