Monad m
とMonad n
という2つのモナドがある場合、m (n a)
をn (m a)
に変換したいと思います。しかし、(>>=)
とreturn
の両方が1つのモナドタイプしか扱っていないため、(>>=)
はモナドからコンテンツを抽出することができますが、同じモナドタイプに戻して結果値にすることができます。モナドの再パック - 一般的な方法?
ただし、m
を固定タイプに設定すると、ジョブが簡単になります。例としてMaybe
を取る:
reorder :: (Monad n) => Maybe (n a) -> n (Maybe a)
reorder Nothing = return Nothing
reorder (Just x) = do
x' <- x
return $ Just x'
またはリスト:
reorder :: (Monad n) => [n a] -> n [a]
reorder [] = return []
reorder (x:xs) = do
x' <- x
xs' <- reorder xs
return (x':xs')
ない見にくい、私たちはここにパターンを持っています。より明白にするために、Applicative
方法でそれを書き、それが各要素にデータコンストラクタを適用するよりも、よりません:
reorder (Just x) = Just <$> x
reorder (x:xs) = (:) <$> x <*> (reorder xs)
私の質問です:Haskellの型クラスは、すでに私はそのような動作を記述するために存在する、または実行ん自分自身で車輪を発明しなければなりませんか?
私はGHCのドキュメントで簡単な検索を行いましたが、このトピックでは役に立たないものは見つかりませんでした。
これはもちろん、外側の型のコンストラクタが 'Traversable'(すべての' Monad'sではない)である場合にのみ機能します。ボーナスは、内側のものが 'Applicative'でなければならないということです。 –