11

これは問題を探す解決策かもしれません...もしそうなら、私はあなたの耽溺をお願いします!

可能な実装:

class Switch' f where
  switch :: f a -> f ()

instance Switch' [] where
  switch []     = [()]
  switch (_:_)  = []

instance Switch' Maybe where
  switch Nothing   = Just ()
  switch (Just _)  = Nothing

解釈は次のようになります。成功した計算が与えられた場合、それを失敗したものにします。失敗した計算が与えられたら、それを成功させます。よくわかりませんが、これはMonadPlusとは逆のようです...本当に目を細めている場合。???

この概念の標準の型クラスまたはその他の実装はありますか?もしあれば、基礎となる数学はどのように見えるでしょうか(つまり、これは半群、ループなどです)?

4

3 に答える 3

8
switch :: (Alternative f, Eq (f a)) => f a -> f ()
switch x | x == empty = pure ()
         | otherwise = empty

また

switch :: (MonadPlus m, Eq (m a)) => m a -> m ()
switch x | x == mzero = return ()
         | otherwise = mzero
于 2012-10-30T20:38:20.440 に答える
4

私は一般的な解決策を持っていますが、それは左キャッチMonadPlus法則に従うインスタンスに対してのみ機能します(そして、それはおそらく必要条件にすぎず、十分ではありません):

isZero :: (MonadPlus m) => m a -> m Bool
isZero x = (x >> return False) `mplus` return True

switch :: (MonadPlus m) => m a -> m ()
switch x = isZero x >>= \r -> if r then return () else mzero

それもうまくSTMいきます。

(ただし、常に返されるリストの場合[()]、この定義は左分布を満たすものには機能しないと思います。)

は の値を検査しますが、アプリケーションではそれができないApplicativeため、 sに対してこのように定義することはできません。(そして、左キャッチ規則を満たすインスタンスが法則を満たすことはめったにありません。)switchisZeroMonadPlus Applicative

switch . (switch :: m () -> m ()) = idとにかく、この定義が成り立つかどうかを確認することは興味深いでしょう。

于 2012-10-31T14:45:11.797 に答える