函数是否可以在非nullary类型构造函数上参数化多态?

时间:2016-06-23 12:18:46

标签: haskell higher-kinded-types

在Haskell中,在处理ad hoc多态时,有很多高kinded多态的例子,如Monad和Functor。但是,我想不出参数多态的任何例子。

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

3 个答案:

答案 0 :(得分:2)

如果您仍然允许类型类约束,那么答案是,确定!例如。我仍然会打电话给

<li><a href="{{ URL::to('/static/page/'.$page->page_id) }}">{{ $page->page_title }}</a></li>

参数多态。但我想这不是你的想法。

另一件显然可能的事情就是仅限制类型以具有特定形式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

你可以签名

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 的类型信息,但保证实现不能尝试在运行时评估参数。

但要执行此操作的standard way

l

or

  minimumLength :: Tagged (l a) Int

一般来说, minimumLength :: Proxy (l a) -> Int 无法用f a做任何事情,所以基本上你可以将任何这样的高阶参数函数的类型重写为第一个 - 命令参数多态。

答案 1 :(得分:2)

你完全可以做到这一点。类型同义词pigworker喜欢:

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

由于我实际上并不知道的原因,这代表了仿函数fg之间的自然转换(无论是什么)。但是函数可以采用f ~> g类型的参数,并将其应用于任意数量的f a类型。使用非常规类型(特别是高阶嵌套数据类型,例如Ralf Hinze,在Numerical Representations as Higher-Order Nested Datatypes中探讨过),它可以应用于无限数量的不同类型。

一个人为的例子:

{-# 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)

hellofg类型中具有多态性,每种类型都有* -> *种。 †我认为将此转换为仅使用类型*可能需要进行非平凡的重构。

†事实上,如果您启用PolyKinds,则fg会分别采用多边形类型k -> *

答案 2 :(得分:1)

我非常喜欢的一个例子是p运算符,用于按其长度索引的列表:它在类Nat -> *的谓词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) 而非必须进行模式匹配。

{{1}}

我已上传a complete gist,其中包含所有正确的语言扩展程序以及与这些类型相对应的代码,以防您想要查看。