限制类型参数在数据声明中可以采用的类型

Geo*_*rge 0 haskell types singleton-type

我知道Haskell具有参数化的数据类型:

data Maybe a = Nothing | Just a
Run Code Online (Sandbox Code Playgroud)

但有没有办法限制a可以表示的类型?特别是,我想创建一个类型

data Tag a = Tag a
Run Code Online (Sandbox Code Playgroud)

这样a可以采取两种类型TagPrimitive 类型TagComplex(但是,我不希望它是可能的,a是的类型,比方说,IntegerString什么的,让我的程序没有意义).

这可能吗?

Cac*_*tus 7

您可以使用通常的singleton-y方法:

{-# language GADTs #-}

data Taggable a where
  Primitive : Taggable TagPrimitive
  Complex : Taggable TagComplex
Run Code Online (Sandbox Code Playgroud)

然后定义Tag

data Tag a where
  Tag : Taggable a -> a -> Tag a
Run Code Online (Sandbox Code Playgroud)

然后当你发送a给定Tag值时,你可以匹配单例:

 f :: Tag a -> T
 f (Tag Primitive x) = ... - here, you know x :: TagPrimitive
 f (Tag Complex x) = ... -- here, you know x :: TagComplex
Run Code Online (Sandbox Code Playgroud)

或者,如@rampion在评论中提到,你可以折叠TaggableTag,留给你

data Tag a where
  Primitive :: TagPrimitive -> Tag TagPrimitive
  Complex :: TagComplex -> Tag TagComplex
Run Code Online (Sandbox Code Playgroud)