簡體   English   中英

Ed Kmett的遞歸方案包中的Fix,Mu和Nu有什么區別

[英]What is the difference between Fix, Mu and Nu in Ed Kmett's recursion scheme package

在Ed Kmett的recursion-scheme包中,有三個聲明:

newtype Fix f = Fix (f (Fix f))

newtype Mu f = Mu (forall a. (f a -> a) -> a)

data Nu f where 
  Nu :: (a -> f a) -> a -> Nu f

這三種數據類型有什么區別?

Mu表示遞歸類型作為其折疊, Nu表示它作為其展開。 在Haskell中,這些是同構的,並且是表示相同類型的不同方式。 如果你假裝Haskell沒有任意遞歸,這些類型之間的區別變得更有趣: Mu f是最少的(最初的)固定點fNu f是其最大的(終端)的固定點。

f的固定點是Tf T之間的類型T同構,即in :: f T -> Tout :: T -> f T的一對反函數。 類型Fix只使用Haskell的內置類型遞歸來直接聲明同構。 但是你可以實現MuNu輸入/輸出。

舉一個具體的例子,假裝你不能寫遞歸值。 Mu Maybe的居民Mu Maybe ,即值:: forall r. (Maybe r -> r) -> r :: forall r. (Maybe r -> r) -> r ,是自然的,{0,1,2,...}; Nu Maybe的居民,即值:: exists x. (x, x -> Maybe x) :: exists x. (x, x -> Maybe x) ,是conaturals {0,1,2,...,∞}。 想想這些類型的可能價值,看看為什么Nu Maybe有一個額外的居民。

如果你想對這些類型有一些直覺,那么在沒有遞歸的情況下實現以下內容可能是一種有趣的練習(大致按難度遞增順序):

  • zeroMu :: Mu MaybesuccMu :: Mu Maybe -> Mu Maybe
  • zeroNu :: Nu MaybesuccNu :: Nu Maybe -> Nu MaybeinftyNu :: Nu Maybe
  • muTofix :: Mu f -> Fix ffixToNu :: Fix f -> Nu f
  • inMu :: f (Mu f) -> Mu foutMu :: Mu f -> f (Mu f)
  • inNu :: f (Nu f) -> Nu foutNu :: Nu f -> f (Nu f)

您也可以嘗試實現這些,但它們需要遞歸:

  • nuToFix :: Nu f -> Fix ffixToMu :: Fix f -> Mu f

Mu f是最不固定的點, Nu f是最大的,所以寫一個函數:: Mu f -> Nu f很容易,但寫一個函數:: Nu f -> Mu f很難; 就像在逆流而行。

(有一點,我的意思是寫出這些類型的更詳細的解釋,但這種格式可能有點太長了。)

暫無
暫無

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

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