显示异构列表的实例

时间:2018-05-13 17:26:32

标签: haskell dependent-type heterogeneous

我无法为下面定义的异构列表定义Show实例:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE FlexibleInstances #-}

import Data.Kind

data HList xs where
     HNil :: HList TNil
     (::^) :: a -> HList as -> HList (a :^ as)

data TypeList = TNil | (:^) Type TypeList

instance Show (HList TNil) where
     show HNil = "[]"

如果Typelist xs中的所有类型都有Show Instance,我想给HList xs一个show实例。我想一个人应该能写出像

这样的东西
instance (Show a, _) => Show (HList a :^ as) where
     show (x ::^ xs) = show x ++ show xs

但我不确定要填什么洞_。

PS:如果您在ghci中尝试此操作,请不要忘记添加语言扩展程序

:set -XTypeInType -XTypeOperators

1 个答案:

答案 0 :(得分:4)

使用类型族,您可以表达约束"所有类型都有一个show instance"非常直接:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}

import Data.Kind

infixr 5 ::^
data HList xs where
     HNil :: HList TNil
     (::^) :: a -> HList as -> HList (a :^ as)

data TypeList = TNil | (:^) Type TypeList

type family All (c :: Type -> Constraint) (xs :: TypeList) :: Constraint where
        All c TNil = ()
        All c (x :^ xs) = (c x, All c xs)

instance All Show xs => Show (HList xs) where
    show HNil = "[]"
    show (x ::^ xs) = '[' : show x ++ go xs
      where
        go :: All Show ys => HList ys -> String
        go HNil = "]"
        go (y ::^ ys) = ',' : show y ++ go ys