1. ホーム
  2. haskell

[解決済み] フリーモナドとは何ですか?

2022-03-23 12:19:26

質問

という言葉を目にしたことがあります。 フリーモナド ポップアップ あらゆる そして では しかし、誰もが、それが何であるかの説明をすることなく、ただそれを使ったり、議論したりしているように見えます。では、フリーモナドとは何でしょうか?(私はモナドとHaskellの基本には詳しいですが、カテゴリ理論については非常に大まかな知識しかありません)。

どのように解決する?

Edward Kmettの回答は明らかに素晴らしい。 しかし、少し専門的です。 ここでは、おそらくもっとわかりやすい説明をします。

フリーモナドはファンクタをモナドに変換する一般的な方法にすぎません。 つまり、任意のファンクタ f Free f はモナドである。 これは、関数のペアを得ることを除けば、あまり有用ではないでしょう。

liftFree :: Functor f => f a -> Free f a
foldFree :: Functor f => (f r -> r) -> Free f r -> r

これらのうち、最初のものはモナドに入るためのもので、2番目のものはモナドから出るためのものです。

より一般的には、XがYに何らかの追加要素を加えたものである場合、quot;free X"は、YからXへ、何も追加要素を得ることなく移動する方法であると言えます。

例:モノイド(X)とは、基本的に操作(足し算が考えられる)と恒等式(ゼロなど)を持つという追加構造(P)を持つ集合(Y)である。

そこで

class Monoid m where
   mempty  :: m
   mappend :: m -> m -> m

さて、私たちはリストを知っています。

data [a] = [] | a : [a]

さて、どんな型でも t は知っています。 [t] はモノイドである

instance Monoid [t] where
  mempty   = []
  mappend = (++)

ということで、リストは集合(あるいはHaskellの型)の上の"free monoid"である。

なるほど、フリーモナドも同じような考え方ですね。 ファンクタを受け取って、モナドを返すんです。 実際、モナドはエンドファンクタのカテゴリにおけるモノイドと見なすことができるので、リスト

data [a] = [] | a : [a]

は、自由モナドの定義によく似ています。

data Free f a = Pure a | Roll (f (Free f a))

と、その Monad のインスタンスと類似しています。 Monoid リストのインスタンス

--it needs to be a functor
instance Functor f => Functor (Free f) where
  fmap f (Pure a) = Pure (f a)
  fmap f (Roll x) = Roll (fmap (fmap f) x)

--this is the same thing as (++) basically
concatFree :: Functor f => Free f (Free f a) -> Free f a
concatFree (Pure x) = x
concatFree (Roll y) = Roll (fmap concatFree y)

instance Functor f => Monad (Free f) where
  return = Pure -- just like []
  x >>= f = concatFree (fmap f x)  --this is the standard concatMap definition of bind

ここで、2つのオペレーションを取得します。

-- this is essentially the same as \x -> [x]
liftFree :: Functor f => f a -> Free f a
liftFree x = Roll (fmap Pure x)

-- this is essentially the same as folding a list
foldFree :: Functor f => (f r -> r) -> Free f r -> r
foldFree _ (Pure a) = a
foldFree f (Roll x) = f (fmap (foldFree f) x)