2017-02-09 18 views
1

私は状態モナドhereを通じてつもりだと私が実装しようとしている:状態モナドを実装するときのデータコンストラクタエラー?

import Control.Monad.Reader 
import Control.Monad.Writer 
import Control.Monad.State 

type Stack = [Int] 

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

は、しかし、私は次のエラーを取得しています:

"Data constructor not in scope: 
    State :: ([t0] -> (t0, [t0])) -> State Stack Int 
Perhaps you meant one of these: 
    ‘StateT’ (imported from Control.Monad.State), 
    variable ‘state’ (imported from Control.Monad.State)" 

私はここで基本的な何かが足りないのですか?

答えて

4

んが、あなたがいないではありません。このチュートリアルではちょっと単純化しています(、それともちょうど古くなったのでしょうか?私は2つのうちどちらが古くなっているかを知るには十分遠くはありません)。 Control.Monad.Stateは、モナド変換器StateTを定義します。また、コンストラクタがStateではないことを意味している。しかし、チュートリアルでは、あなたの

type State s a = StateT s Identity a 

を教えているものと同等の単純型シノニムをエクスポートし、それがStateTである(そして、それは一般的な署名を持っています)。ありがたいことに、あなたはそれについてあまり心配する必要はありません。 Stateを構築するための

  • 、あなたはstate機能を使用して、それが(実際に、それはより一般的な署名がある - あなたがエラーメッセージに遭遇する)署名state :: (s -> (a,s)) -> State s aを持っているふりをすることができます。
  • Stateを解体するには、パターンマッチングの代わりにrunState :: State s a -> s -> (a,s)を使用してください。例から

あなたが与えた:それはチュートリアルが言うことですので

import Control.Monad.Reader 
import Control.Monad.Writer 
import Control.Monad.State 

type Stack = [Int] 

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

アレックさん、ありがとうございました - 私は老いていないのでうれしいです! –

+0

[リンクされたチュートリアルは古いものであり、単純化していません。](http://hackage.haskell.org/package/mtl-1.0/docs/Control-Monad-State。html#t:State)「アイデンティティ」に階層化されたトランスフォーマーには、対応するモナドを直接定義するのと比較してランタイムコストがかかっていると心配していた時代があり、多くのライブラリ(mtlを含む)最終的には、これに対するコードの重複/保守負担の議論が、それに対するパフォーマンスの議論を勝ち取った。 –

2

State aへのインターフェイスが、関数をラップするデータコンストラクタを介しているとします。s -> (a, s)?これは簡単な方法です州を実装しますが、あなたはそのインターフェイスを提供していません。代わりに、Control.Monad.Stateで提供される構成を使用してください。

一つの簡単な変更だけで、この目的のために設計された小文字state機能を使用することです。また、代わりに国家のこの低レベルのビューでの作業のため、あなたは同じように操作することができ

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

をそのputget機能を通じてモナド:

pop :: State Stack Int 
pop = do 
    (x : xs) <- get 
    put xs 
    return x 
+2

彼女はState' 'にそのインターフェイスを想定しています。 ://'' Control.Monad.State'モジュールはステートフルな計算をラップするnewtypeを提供します: 'newtype State a = State {runState :: s - >(a、s)}' " – Alec

+0

パターンシノニムが賢明であるかどうか疑問に思っています。シンプルなインターフェースでシンプルな 'State'を使って作業するという"錯覚 "を書き出すためです。安全な変換を使用すると、ランタイムコストがゼロになるはずです。これは、「アイデンティティ」に適用されるほとんどのモナド変圧器に拡張することができます。 – chi

関連する問題