2016-05-13 7 views
0

私はいくつかの計算を表す私のモナドを書いています。ここで、計算をどのようにしてsequencedにするかを定義したいと思います。だから、私は>>=を定義するつもりです。しかし、流れの制御は、私にコンクリートタイプaに集中することを余儀なくさせました。私は意味する:特定のMonad。ハスケル

m >>= f = 
    a <- m 
    case a of 
     (ParticularParameterA) -> doSomething 
      .......... 

それは適切な解決策ですか?つまり、私は関数型プログラミングの経験がないので、それを行うのは大丈夫かどうかわかりません。それをより良くするには?

+1

「m」は、モナドインスタンスによって固定タイプである必要があります。したがって、切り替えが必要ないし、可能でもないはずです。モナドタイプのコンストラクタを選択/切り替えていることを意味しますか? – MicroVirus

+0

はい、確かにあります。私は編集しました。 – Gilgamesz

+0

あなたの編集はコードを無意味なものにしました。doブロック/リストの理解の外に '<'があります。 – MicroVirus

答えて

1

それはあなたの状況は、単純なパターンに陥る可能性がある場所であればフォームのごモナド:Stateはあなた自身を設計したデータ型である

newtype MyMonad a = MyMonad { run :: State -> (a, State) } 

。ポイントは、あなたはおそらく機能していされています

run :: MyMonad a -> State -> (a, State) 

を、あなたはおそらく、(>> =)を実装する際に、この機能を使用する必要があります。

m >>= f = MyMonad(\state -> let (x, newState) = run m state in 
           case x of 
           (ParticularParameterA) -> doSomething 
           .......... 

あなた\state -> ...機能が(b, State)を返す必要がありますf::a -> MyMonad b場合、だからおそらくあなたのコードのどこかにrun (f x) newStateを使いたいと思うでしょう。あなたのモナド型は以下のようであれば

newtype MyMonad a = MyMonad { run :: State -> Maybe (a, State) } 
newtype MyMonad a = MyMonad { run :: State -> Either String (a, State) } 

は、あなたがまだrun機能を使用して、例えば

m >>= f = MyMonad (\state -> case run m state of 
           Just (x, newState) -> run (f x) newState 
           Nothing    -> Nothing) 
2

case文にもかかわらず、doブロック内のバインディングが>>=の使用に変換されるため、この定義は実際には明らかに無意味です。したがって、既存のコードでは、m >>= f = m >>= \a -> ...が定義されています。これは、無限ループと1つのスペースリークの両方です。