Haskell 如何描述函数必须接受某个构造函数并返回其实例?

Haskell 如何描述函数必须接受某个构造函数并返回其实例?,haskell,Haskell,我有以下数据类型: data MyData = D1 {several_records} | D2 {several_records} | D3 {several_records} | 如何创建一个函数,使其接受MyData并返回MyData,但它接受的参数和返回类型必须属于MyData的同一构造函数 myFunc :: MyData -> MyData -- not presicely what I want 请注意,在我的实际项目中,我有更多的MyData构造函数,因此简单地为M

我有以下数据类型:

data MyData = D1 {several_records} | D2 {several_records} | D3 {several_records} | 
如何创建一个函数,使其接受
MyData
并返回
MyData
但它接受的参数和返回类型必须属于
MyData
的同一构造函数

myFunc :: MyData -> MyData -- not presicely what I want
请注意,在我的实际项目中,我有更多的
MyData
构造函数,因此简单地为
MyFunc
逐个枚举它们并不是我想要的——我想一次概括它们。

使用GADT,也许:

{-#语言数据类型、GADT、KindSignatures}
数据MyDataTag=DT1 | DT2 | DT3
数据MyData::MyDataTag->*其中
D1:{foo_record::Int,bar_record::String}->MyData'DT1
D2::{baz_record::Char}->MyData'DT2
D3::{qux_record::Double}->MyData'DT3
myFunc::MyData a->MyData a
myFunc(D1 foo-bar)=D1(foo+1)(bar++“你好”)
myFunc(D2_uz)=D2'x'
myFunc(D3-qux)=D3(-qux)

显然,您可以将函数定义为
f::MyData->MyData;f(D1 uu)=D1 uu;f(D2)D2
。等等,那么您是在问如何在类型级别强制执行此操作,以使违反此条件的尝试不会进行类型检查吗?或者,您是在问如何以某种系统方式编写一个处理数百个此类构造函数的函数,而不必显式地写出它们?由
D1
创建的值与由
D2
创建的值之间没有类型级别的区别。如果要反映
myFunc(D1…
只能在
myFunc
类型中返回由
D1
创建的值的约束,则需要以不同的方式定义类型。所有构造函数中的记录都相同吗?构造函数类型不必使用
的DT1
,等等?不,重读我的问题carefully@chepner您并不总是需要
(我认为只有在出现歧义时才需要,这里没有),尽管您确实会收到一条警告(
-Wunticked-promoted-constructor
)。我还是要加上它。@Jarru你能详细说明一下这有什么问题吗?@Jarru在这种情况下,我认为如果你发布你的实际
MyData
myFunc
,而不是像现在这样(特别是为了让我们能看到
myFunc
实际上做了什么),这将更容易解决。