私は、HaskellライブラリControl.Monad.Freeからhoistfree関数に関するいくつか質問があります。 2つのファンクタの間の変換f
が与えられた場合、ホイストフリーfは対応するフリーモナドの間にモーフィズムを生成する。ここにその定義があります。hoistfreeの定義
hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b
hoistFree _ (Pure a) = Pure a
hoistFree f (Free as) = Free (hoistFree f <$> f as)
質問1どのようにHaskellは<$>
がg
にないf
、Free f
またはFree g
に関連したマップであることを知っていますか? hoistfreeが
hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b
hoistFree _ (Pure a) = Pure a
hoistFree f (Free as) = Free (f (hoistFree f <$> as))
として定義されていないのはなぜ
質問2?
f
が自然な変換である場合、これら2つの定義は一致します。しかし、第2の定義は、常に関係を満足する。
hoistfree f = iter (wrap . f) . map return
これはかなり自然に見える。さらに、iter_map f g = iter f . map g
を使用して表現できる基本的な機能がいくつかあります。例えば、
(=<<) f = iter_map wrap f
質問3はiter_mapどこかで定義されていますか?それはモナドのmapreduceのように見えます。私はベースライブラリでそれを見ませんでした。融合と写像に何らかの利得がありますか?他のいくつかの言語では、これが当てはまりますが、私はHaskellについてはわかりません。ためg
から<$>
を選択する型推論、の
'hoistFree'の定義上のFunctorの制約は間違っていますか?推論型は 'Functor f =>(f(Free g a) - > g(Free g a)) - > Free f a - > Free g a'です。 – Michael
@マイケルなぜ私はより広いタイプが推定されないのか分かりません。これは私にとって謎です。 – stackman
タイプ推論はランク2タイプを推論しませんか、それとも意味ですか?これは、より多くの場合に適用されるという意味での「ワイドタイプ」です。 – Michael