为多个类型变量定义一个约束 [英] Define a constraint for multiple type variables

查看:70
本文介绍了为多个类型变量定义一个约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码库中,我有几种类型,类型变量数量不同.

In my codebase I have several types with a different number of type variables.

例如,考虑

data MyType a b c = ...
data MyOtherType a b c d e = ...

然后我要使用这些类型定义函数,我想要求每个类型变量都是Show的实例.

Then I am defining functions using these types and I want to require that every type variable is an instance of Show.

为了避免过多的重复,我使用ConstraintKinds定义类型

To avoid too much repetition I used ConstraintKinds to define types

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)

以便在我的功能定义中可以使用

so that in the definition of my functions I can use

f :: (Show5 a b c d e) => MyOtherType a b c d e -> ...

现在我的问题是:有没有一种方法可以简化类型Show2,...,Show5的定义?看来它们的定义是递归的,我想知道是否有扩展允许我一次性定义它们

Now my question is: is there a way to simplify the definition of types Show2, ..., Show5? It looks like their definition is recursive and I was wondering if there was an extension which allowed me to define them in one go

推荐答案

您可以使用类型族和类型级别的类型列表.

You could use a type family, and type-level lists-of-types.

{-# 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')

这篇关于为多个类型变量定义一个约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆