Haskell中的无限(最终周期性)HList

时间:2016-05-04 17:41:26

标签: haskell types dependent-type hlist

让我们说我有无限的动作序列,每个动作都返回某种类型的结果。类似的东西:

newtype Stream a = Stream (IO (a, Stream a))

a会随着时间而变化。我想强烈输入这个序列。对于任意无限类型序列和天真的方法来说,显然不会产生这样的结果:

data HStream :: [u] -> * where Cons :: Proxy x -> HStream xs -> HStream (x ': xs)

infiniteInt = Cons (Proxy :: Proxy Int) infiniteInt

将导致无限类型,Haskell的类型系统不支持。但是我没有看到最终周期性的HLists没有任何问题(即,从某个点开始重复自己的类型序列:[Bool, Int, Int, Sting, Int, Sting, Int, Sting ... ])。而且我还认为,如果我们有一些强烈规范化的方式来描述无限类型或某种方式来提供无限类型相等的证据,可以在有限数量的步骤中进行检查,那么应该可以用这种无限类型来检查程序。 / p>

有谁知道如何在Haskell中表示和使用这些类型?现在让我们从无限的最终周期hlist开始,但是如果有人知道如何将它推广到更广泛的无限类型以及泛化限制的范围,我也会感激。

2 个答案:

答案 0 :(得分:5)

使用这个One Cool Trick让HList无限且周期性!

向定期异构流添加元素时,请不要扩展其索引类型列表。旋转它。

type family Append x xs where
    Append x '[] = '[x]
    Append x (y ': xs) = y ': Append x xs

infixr 5 :::
data HStream as where
    (:::) :: { headHS :: a, tailHS :: HStream (Append a as) } -> HStream (a ': as)

myHStream :: HStream '[Char, Bool, Int]
myHStream = 'c' ::: True ::: 3 ::: 'x' ::: False ::: -5 ::: myHStream

答案 1 :(得分:1)

一个通用选项是从编码所有元素类型的HList切换到类型对齐列表(或者更一般地,类型对齐的序列),这只能确保转换顺序有效路径。

data TAList c x z where
  Nil :: TAList c x x
  Cons :: c x y -> TAList c y z -> TAList c x z

因此,您可以谨慎地对转场进行编码,使用c的可能性较大的GADT以及xz的适当选择。无限类型对齐列表没有问题,因为它们在最终类型参数中具有多态性。

您可以使用McBride风格的索引方案而不是Atkey方案来获得更大的灵活性,但代价是更复杂。