我正在通過Richard Bird和Ross Paterson的論文De bruijn notation as a nested datatype。在一個一個點上的一個術語摺疊操作被定義爲:haskell中的類型級多態性
infixl 9 :@
data Expr a =
Var a
| (Expr a) :@ (Expr a)
| Lam (Expr (Maybe a)
foldT ::
(forall a. a -> n a) ->
(forall a. n a -> n a -> n a) ->
(forall a. n (Maybe a) -> n a) ->
Expr b -> n b
foldT v _ _ (Var x) = v x
foldT v a l (fun :@ arg) = a (foldT v a l fun) (foldT v a l arg)
foldT v a l (Lam body) = l (foldT v a l body)
...並進一步爲通用版本,允許自由瓦爾值的操作:
gfoldT ::
(forall a. m a -> n a) ->
(forall a. n a -> n a -> n a) ->
(forall a. n (Maybe a) -> n a) ->
(forall a. (Maybe (m a)) -> m (Maybe a)) ->
Expr (m b) -> n b
gfoldT v _ _ _ (Var x) = v x
gfoldT v a l t (fun :@ arg) = a (gfoldT v a l t fun) (gfoldT v a l t arg)
gfoldT v a l t (Lam body) = l (gfoldT v a l t (mapT t body))
然後,作者狀態:
從理論上講,我們可以採取
m = id
,身份類型構造,並 因此獲得foldT v a l = gfoldT v a l id
。 (...)但是,類型 haskell中的構造函數多態性是有限的,在該類型中 構造函數變量可能只能實例化爲數據類型 構造函數。
而且他們進一步表示,爲此,我們需要一次性的專門功能,如上面的foldT
。
我想知道究竟是什麼type constructor polymorphism
意味着在這方面(類似全System F
?),如果像foldT v a l = gfoldT v a l id
可以通過新增加的類型層次的編程功能的手段像 DataKinds
,PolyKinds
或TypeFamilies
來實現。
引用源時,使用* actual *引用塊,而不是斜體。語義結構可以被例如盲人屏幕閱讀器利用,以更好地呈現該問題。 – Bakuriu
@Bakuriu,屏幕閱讀器不會識別雙引號嗎?我同意引用塊對於這樣長的東西肯定是可取的,但我很好奇。 – dfeuer
@Bakuriu,謝謝你的提示! – jules