如何在Haskell中定义恒定异构流?

Mar*_*mán 8 haskell type-families coinduction

我了解如何在 Haskell 中定义同构流和异构流。

-- Type-invariant streams.
data InvStream a where
   (:::) :: a -> InvStream a -> InvStream a

-- Heterogeneous Streams.
data HStream :: InvStream * -> * where
   HCons :: x -> HStream xs -> HStream (x '::: xs)
Run Code Online (Sandbox Code Playgroud)

我们如何将恒定流定义为异构流的特殊情况?如果我尝试定义常量类型流的类型族,则会收到“归约堆栈溢出”错误。我想这与类型检查算法不够懒惰并试图计算整个Constant a类型流有关。

type family Constant (a :: *) :: InvStream * where
  Constant a = a '::: Constant a

constantStream :: a -> HStream (Constant a)
constantStream x =  HCons x (constantStream x)
Run Code Online (Sandbox Code Playgroud)

有什么方法可以解决这个问题并定义恒定的异构流吗?我应该尝试其他类似的结构吗?

lef*_*out 9

这正是归纳共归纳类型之间的区别,而我们在 Haskell 中很喜欢忽略这一点。但你不能在类型级别上做到这一点,因为编译器需要在有限的时间内进行证明。

因此,我们需要的是以共归纳的方式实际表达类型级流:

{-# LANGUAGE GADTs, DataKinds, TypeFamilies #-}

import Data.Kind (Type)  -- The kind `*` is obsolete

class TypeStream (s :: Type) where
  type HeadS s :: Type
  type TailS s :: Type

data HStream s where
  HConsS :: HeadS s -> HStream (TailS s) -> HStream s

data Constant a

instance TypeStream (Constant a) where
  type HeadS (Constant a) = a
  type TailS (Constant a) = Constant a

constantStream :: a -> HStream (Constant a)
constantStream x = HConsS x (constantStream x)
Run Code Online (Sandbox Code Playgroud)