使用3级(或更高级)多态性的用例?

Tom*_*ett 26 polymorphism haskell types higher-rank-types parametric-polymorphism

我已经看到了一些用于rank-2多态性的用例(最突出的例子是ST monad),但是没有比这更高级别的用例.有谁知道这样的用例?

pig*_*ker 30

我也许可以提供帮助,虽然这种野兽不可避免地有点牵扯.这是我有时用于开发带有绑定和de Bruijn索引的瓶颈语法的模式.

mkRenSub ::
  forall v t x y.                      -- variables represented by v, terms by t
    (forall x. v x -> t x) ->            -- how to embed variables into terms
    (forall x. v x -> v (Maybe x)) ->    -- how to shift variables
    (forall i x y.                       -- for thingies, i, how to traverse terms...
      (forall z. v z -> i z) ->              -- how to make a thingy from a variable
      (forall z. i z -> t z) ->              -- how to make a term from a thingy
      (forall z. i z -> i (Maybe z)) ->      -- how to weaken a thingy
      (v x -> i y) ->                    -- ...turning variables into thingies
      t x -> t y) ->                     -- wherever they appear
    ((v x -> v y) -> t x -> t y, (v x -> t y) -> t x -> t y)
                                                 -- acquire renaming and substitution
mkRenSub var weak mangle = (ren, sub) where
  ren = mangle id var weak         -- take thingies to be vars to get renaming
  sub = mangle var id (ren weak)   -- take thingies to be terms to get substitution
Run Code Online (Sandbox Code Playgroud)

通常情况下,我会使用类型类来隐藏最糟糕的血腥,但是如果你解开字典,这就是你会发现的.

关键是这mangle是一个排名2的操作,它采用了在它们工作的变量集中具有适当操作多态的东西的概念:将变量映射到thingies的操作变成了术语变换器.整个过程展示了如何使用mangle生成重命名和替换.

这是该模式的具体实例:

data Id x = Id x

data Tm x
  = Var (Id x)
  | App (Tm x) (Tm x)
  | Lam (Tm (Maybe x))

tmMangle :: forall i x y.
             (forall z. Id z -> i z) ->
             (forall z. i z -> Tm z) ->
             (forall z. i z -> i (Maybe z)) ->
             (Id x -> i y) -> Tm x -> Tm y
tmMangle v t w f (Var i) = t (f i)
tmMangle v t w f (App m n) = App (tmMangle v t w f m) (tmMangle v t w f n)
tmMangle v t w f (Lam m) = Lam (tmMangle v t w g m) where
  g (Id Nothing) = v (Id Nothing)
  g (Id (Just x)) = w (f (Id x))

subst :: (Id x -> Tm y) -> Tm x -> Tm y
subst = snd (mkRenSub Var (\ (Id x) -> Id (Just x)) tmMangle)
Run Code Online (Sandbox Code Playgroud)

我们只实现了一次遍历遍历,但是以非常一般的方式,我们通过部署mkRenSub模式(它以两种不同的方式使用一般遍历)来获得替换.

再举一个例子,考虑类型运算符之间的多态操作

type (f :-> g) = forall x. f x -> g x
Run Code Online (Sandbox Code Playgroud)

一个IMonad(索引单子)的一些m :: (* -> *) -> * -> *配备了多态运营商

ireturn :: forall p. p :-> m p
iextend :: forall p q. (p :-> m q) -> m p :-> m q
Run Code Online (Sandbox Code Playgroud)

所以那些操作是第2级.

现在任何由任意索引monad参数化的操作都是秩3.因此,例如,构造通常的monadic组合,

compose :: forall m p q r. IMonad m => (q :-> m r) -> (p :-> m q) -> p :-> m r
compose qr pq = iextend qr . pq
Run Code Online (Sandbox Code Playgroud)

一旦解压缩定义,依赖于3级量化IMonad.

故事的道德:一旦你在多态/索引概念上进行更高阶的编程,你的有用工具包的词典就会变成第2级,你的通用程序就会变成第3级.当然,这可能会再次升级.

  • 不知怎的,我知道康纳会回答这个问题:-) (2认同)

Dan*_*ner 9

也许我读过的摘要的最好结局是:"除了Haskell的普通类型类机制之外,Multiplate只需要3级多​​态性." .(哦,只有3级多态,没什么大不了的!)