在我的代码库中,我有几种类型,类型变量数量不同。
例如,考虑
data MyType a b c = ...
data MyOtherType a b c d e = ...
然后我要使用这些类型定义函数,我想要求每个类型变量都是Show
的实例。
为了避免过多的重复,我使用ConstraintKinds
定义类型
type Show2 a b = (Show a, Show b)
type Show3 a b c = (Show2 a b, Show c)
type Show4 a b c d = (Show3 a b c, Show d)
type Show5 a b c d e = (Show4 a b c d, Show e)
以便在我的功能定义中可以使用
f :: (Show5 a b c d e) => MyOtherType a b c d e -> ...
现在我的问题是:是否有一种方法可以简化类型Show2
,...,Show5
的定义?看来它们的定义是递归的,我想知道是否有扩展允许我一次定义它们
答案 0 :(得分:5)
您可以使用类型族和类型级别的类型列表。
{-# LANGUAGE TypeFamilies, DataKinds, TypeOperators #-}
import Data.Kind
type family ShowN (xs :: [*]) :: Constraint
type instance ShowN '[] = ()
type instance ShowN (t ': ts) = (Show t, ShowN ts)
foo :: ShowN '[a, b, c] => a -> b -> c -> String
foo xa xb xc = show xa ++ " " ++ show xb ++ " " ++ show xc
main :: IO ()
main = putStrLn (foo 3 True 'f')