2

特定のデータ型のMonadインスタンスを宣言する必要があります。

data M m a = Mk (m (Maybe a))

instance (Monad m) => Monad (M m) where
  return x = Mk (m (Just x))
  Mk (m (Nothing)) >>= f = Mk (m (Nothing))
  Mk (m (Just x)) >>= f = f x

しかし、私は得ます:

test.hs:6:7: Parse error in pattern: m
Failed, modules loaded: none.

とても簡単かもしれませんが、わかりません!

4

2 に答える 2

5

型変数は、特にとmを区別するために、パターンマッチングできるものではありません。代わりに使用されるさまざまな可能なタイプの意味を考えてください。多くの場合、このようなパターンマッチングは完全に不可能です。JustNothingm

そのインスタンスを作成するには、次のようなものが必要です。

instance (Monad m) => Monad (M m) where
  return x = Mk (return (Just x))
  Mk mx >>= f = -- ??

returnタイプの値を作成するために使用されることに注意してください。m (Maybe a)これは制約のために可能でMonad mあり、一般的な場合(制約がまったくない場合)、そのような値を作成する方法はありません。

実装(>>=)するには、同様のことを行う必要があります。同様に(>>=)、のMonadインスタンスを利用しますm

ちなみに、特別な理由がない限り、 newtypeforの使用を検討する必要があります。ほとんどの場合、使用できるのであれば、使用する必要があります。Mdatanewtype

于 2013-02-14T16:27:51.747 に答える
0

コンストラクターでのみパターン マッチを実行できます。他のものでは実行できません。内部にある Maybe データにアクセスするには、m の Monad インスタンスを使用する必要があります。これがあなたが望む動作をするかどうかは 100% 確信が持てませんが、型チェックは行います。

data M m a = Mk (m (Maybe a))

instance (Monad m) => Monad (M m) where
  return x = Mk (return (Just x))
  Mk m >>= f = Mk (m >>= go)
    where go (Just x) = let Mk x' = f x in x'
          go _        = return Nothing
于 2013-02-14T18:40:19.517 に答える