我无法为下面定义的异构列表定义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
答案 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