簡體   English   中英

Haskell的FreeT和Coroutine類型之間有什么關系

[英]what is the relationship between Haskell's FreeT and Coroutine type

Monad.Reader Issue 19中的“Coroutine Pipelines”文章中,作者定義了一個通用的Coroutine類型:

newtype Coroutine f m a = Coroutine
  { resume :: m (Either (f (Coroutine f m a)) a)
  }

我注意到這種類型與free軟件包中的FreeT類型非常相似:

data FreeF f a b = Pure a | Free (f b)

newtype FreeT f m a = FreeT
  { runFreeT :: m (FreeF f a (FreeT f m a))
  }

似乎FreeTCoroutine是同構的。 以下是從一個映射到另一個的函數:

freeTToCoroutine
  :: forall f m a. (Functor f, Functor m) => FreeT f m a -> Coroutine f m a
freeTToCoroutine (FreeT action) = Coroutine $ fmap f action
  where
    f :: FreeF f a (FreeT f m a) -> Either (f (Coroutine f m a)) a
    f (Pure a) = Right a
    f (Free inner) = Left $ fmap freeTToCoroutine inner

coroutineToFreeT
  :: forall f m a. (Functor f, Functor m) => Coroutine f m a -> FreeT f m a
coroutineToFreeT (Coroutine action) = FreeT $ fmap f action
  where
    f :: Either (f (Coroutine f m a)) a -> FreeF f a (FreeT f m a)
    f (Right a) = Pure a
    f (Left inner) = Free $ fmap coroutineToFreeT inner

我有以下問題:

  1. FreeTCoroutine類型之間有什么關系? 為什么“Coroutine Pipelines”的作者不使用FreeT類型而不是創建Coroutine類型?
  2. 免費monad和協同程序之間是否存在某種更深層次的關系? 類型是同構的似乎並不是巧合。
  3. 為什么Haskell中流行的流媒體庫不是基於FreeT

    pipes的核心數據類型是Proxy

     data Proxy a' ab' bmr = Request a' (a -> Proxy a' ab' bmr ) | Respond b (b' -> Proxy a' ab' bmr ) | M (m (Proxy a' ab' bmr)) | Pure r 

    conduit的核心數據類型是Pipe

     data Pipe lioumr = HaveOutput (Pipe lioumr) (m ()) o | NeedInput (i -> Pipe lioumr) (u -> Pipe lioumr) | Done r | PipeM (m (Pipe lioumr)) | Leftover (Pipe lioumr) l 

    我想可以編寫基於FreeTProxyPipe數據類型,所以我想知道它為什么沒有完成? 是出於性能原因嗎?

    我在流行的流媒體庫中看到的FreeT的唯一提示是pipes-group ,它使用FreeT中的項目進行分組。

要回答你的第二個問題,讓我們首先通過查看Free簡化問題。 Free fa允許你構造a f形AST,以便以后減少(也就是說,解釋)。 當比較文章中的monad變換器與未提升的自由構造時,我們可以簡單地選擇Identity for m ,這是從變換器構造基monad的通常做法: Free f = FreeT Identity f

Monad Reader的文章首先介紹了一個提升的Trampoline Monad變換器,所以讓我們首先看一下未提升的版本,其中Identity被刪除:

data Trampoline a = Return a | Bounce (Trampoline a)

如果我們將此與Free進行比較

data Free f r = Pure r | Free (f (Free f r))

稍微斜視一下,我們可以看到我們真正需要做的就是“移除” f結構,就像我們之前“移除” m結構一樣。 所以,我們有Trampoline = Free Identity ,因為Identity沒有結構。 反過來,這意味着這個蹦床是一個FreeT Identity Identity :一種簡單的FreeT Identity Identity協程,無法使用效果確定是否反彈或返回。 這就是這個蹦床和蹦床monad變壓器之間的區別:變壓器允許彈跳與m -actions交錯。

通過一些工作,我們還可以看到生成器和消費者是f特定選擇的免費monad,分別是((,) a)((->) a) 他們的免費monad變換器版本同樣允許它們交錯m -actions(例如,發生器可以在屈服之前請求用戶輸入)。 Coroutine概括兩者f中,AST形狀(固定為f ~ Identity用於蹦床)和其可交錯效果的類型(固定為無影響,或m ~ Identity )為Free 這正是FreeT mf

直覺上,如果Free f是用於構造f形AST的monad那么FreeT mf是用於構造與m提供的效果交錯的f形AST的monad。 如果你稍微眯一下,這正是協同程序的完整概括:在構造的AST的形狀和用於構造它的效果類型上參數化計算的計算。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM