![](/img/trans.png)
[英]Is it possible to write a function of signature `Monad m => m a -> forall r. m r` such that the original return value is preserved?
[英]How to understand that the types a and forall r. (a -> r) -> r are isomorphic
在Thinking with Types一書中, 6.4 Continuation Monad
告訴了類型a
和forall r. (a -> r) -> r
forall r. (a -> r) -> r
是同構的,可以通過以下函數來證明:
cont :: a -> (forall r. (a -> r) -> r)
cont x = \f -> f x
unCont :: (forall r. (a -> r) -> r) -> a
unCont f = f id
在這本書中,它告訴我們任何具有相同基數的兩種類型總是彼此同構的。 所以我試圖找出類型a
和forall r. (a -> r) -> r
的基數forall r. (a -> r) -> r
forall r. (a -> r) -> r
。
假設類型a
的基數是|a|
. 然后對於forall r. (a -> r) -> r
類型forall r. (a -> r) -> r
forall r. (a -> r) -> r
,如何算出它的基數等於|a|
? 函數類型a -> b
具有基數|b|^|a|
, 即|b|
到|a|
的力量 ,所以對於所有forall r. (a -> r) -> r
forall r. (a -> r) -> r
基數為|r|^(|r|^|a|)
。 怎么可能等於|a|
?
我糊塗了。 感謝您提供任何提示!
在多態類型存在的情況下,不能真正定義基數。 現在可以理解,多態類型“不是集合”,正如人們最初可能認為的那樣。 雷諾茲在他的論文“多態不是集合論”中提供了一個著名的開創性論點,證明我們不能簡單地以“平凡”的方式解釋帶有集合的類型並獲得有意義的概念。
事實上,在集合中2^K
和K
是不同的基數,第一個更大。 同樣, 2^(2^K)
大於K
。 然而, FX = 2^(2^X)
(類似於F a = (a -> Bool) -> Bool
)形成一個(協變)函子,我們可以找到一個不動點
newtype T = T ((T -> Bool) -> Bool)
獲得T
與2^(2^T)
同構,這在集合中沒有意義,正是因為它們不能具有相同的基數。
(即使沒有遞歸類型,在存在多態的情況下,也可以通過forall a. (F a -> a) -> a
的編碼獲得上述類型T
)
無論如何,為了解決這個僵局,我們需要將a -> Bool
解釋為不同於函數集2^a
其他東西。 一個可能的解決方案是使用Scott 連續函數,正如 Scott 所做的那樣。 一個相關的解決方案是使用穩定函數(參見 Girard 的“證明和類型”一書),它(如果我沒記錯的話)使T
和T -> Bool
的解釋具有相同的基數(除非兩者都是有限的)。
因此,在存在多態類型的情況下,基數不是用於檢查類型同構的正確工具。 我們真的需要看看是否可以像您在問題中發布的那樣制作同構函數及其逆函數。
基數參數不適用於多態類型(請參閱@chi 的答案)。
但是同構本身可以這樣直觀地解釋:
forall r. (a -> r) -> r
的類型forall r. (a -> r) -> r
forall r. (a -> r) -> r
意思是“如果你給我一個將a
轉換為r
,我可以給你一個r
。哦,我可以為任何可能的r
做到這一點”
履行這樣的承諾的唯一途徑是通過秘密具有a
在我的手。
由於我承諾對任何可能的r
執行此操作,這意味着我對r
本身一無所知,包括如何構造它的值。 我唯一可用的是你給我的a -> r
函數。 調用這種函數的唯一方法是給它一個a
。
這意味着,如果我做出這樣的承諾,我必須已經a
背后偷偷地做了a
。
對於更正式的解釋,請回想一下,“同構”在普通術語中的意思是“可以明確地來回轉換而不會丟失”。 這就是基數論證的意思:如果你有相同數量的東西,你總是可以在它們之間安排一個配對。
在您的問題中,您已經展示了兩種轉換: cont
一種方式轉換, unCont
以另一種方式轉換。 你可以簡單地顯示cont . unCont = unCont . cont = id
cont . unCont = unCont . cont = id
cont . unCont = unCont . cont = id
。 因此類型是同構的。
雖然顯示兩種轉換的存在更正式,但我發現對於這兩種類型如何真正“有點相同”的直覺並不總是令人滿意,因此我在上面給出了直觀的解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.