函数可以在非毫米类型构造方上是参数性多态性的吗?



在Haskell中,在处理临时多态性(例如Monad and functor)时,有许多较高的多态性示例。但是,我想不出任何示例来参数多态性。

这是可能的,如果是这样,我可以有一个有用的例子吗?

如果您仍然允许打字机约束,则答案是, nure !例如。我仍然称

之类的东西
normalise :: (Foldable f, Functor f, Fractional n) => f n -> f n
normalise v = fmap (/sum v) V

参数多态性。但是我想那不是你想到的。

显然可能的另一件事就是禁忌类型以具有特定表格_ _,例如

hmap :: (f a -> f b) -> [f a] -> [f b]
hmap = map

这并不是很引人注目,但是在某些应用程序中可能是对Checker类型的微妙提示而有用的。实际上,这是您解决幻影参数问题的一种方法:而不是

class LengthyList l where minimumLength :: l a -> Int
instance LengthyList [] where minimumLength _ = 0
instance LengthyList NonEmpty where minimumLength _ = 1

您可能会签名

  minimumLength :: p (l a) -> Int

又名

  minimumLength :: proxy (l a) -> Int

因此,您仍然通过l的类型信息,但保证实现无法在运行时评估参数。

但是,这样做的标准方法是

  minimumLength :: Tagged (l a) Int

  minimumLength :: Proxy (l a) -> Int

通常,f a也无法使用fa完成,因此,从本质上讲,您可以将任何此类高阶参数函数的类型重写为一阶参数上的多态性。

您完全可以做到这一点。类型的同义词猪工人喜欢:

type f ~> g = forall a . f a -> g a

由于我实际上不知道的原因,这代表了函子fg之间的自然转换(到底是什么)。但是,一个函数可以对f ~> g类型进行参数,并将其应用于所喜欢的多种类型f a。使用非规范类型(特定于高阶嵌套数据类型,例如Ralf Hinze,例如在数值表示中探索的高阶嵌套数据类型),可以将其应用于无限数量的不同类型。

> > 。

一个人为的例子:

{-# LANGUAGE RankNTypes, TypeOperators #-}
type f ~> g = forall a . f a -> g a
data Two g a = Two (g a) (g a)
data Foo f a = This (f a)
             | That (Foo (Two f) a)
hello :: (f ~> g) -> Foo f a -> Foo g a
hello t (This fa) = This (t fa)
hello t (That buh) =
  That (hello ((Two x y) -> Two (t x) (t y)) buh)

hello在类型fg中是多态性的,每个类型都有 * -> *。†我相信将其转换为仅使用类型的*可能需要非平凡的重构。

‡实际上,如果启用PolyKindsfg将每个都有一个多型类型k -> *

我非常喜欢的一个示例是列表的foldr操作员,该列表由其长度索引:它是acky Nat -> *的谓词p,并保证如果您将其应用于一个长度列表m然后您获得了p m的证明。

这对应于这种类型:

foldr :: forall a (p :: Nat -> *).
         (forall n. a -> p n -> p ('Succ n)) ->
         p 'Zero ->
         forall n. Vec a n -> p n

这个额外的精确度使得实现例如append使用foldr,而不必通过模式匹配进行。

append :: forall a m n. Vec a m -> Vec a n -> Vec a (m :+: n)

我已经上传了一个完整的要点,所有正确的语言扩展已打开,并且代码与这些类型相对应,以防您要窥视。

最新更新