当前位置: 首页 > 知识库问答 >
问题:

用GADTs和typeclass约束对类型变量进行Haskell类型推断

夏骏
2023-03-14

我定义了一个自定义GADT,其中类型构造函数对类型变量有一个类型类约束,如下所示:

data MyGadt x where
  Sample :: Show a => a -> MyGadt a
foo (Sample a) = show a

bar a = Sample a

我假设我不必提到约束,因为它是在GADT定义中声明的。我唯一能想到的部分原因是GADT在函数中的位置。我对此不太了解,但据我所知,mygadtfoo中处于正位置,在bar中处于负位置。

我什么时候必须明确地提到类型类约束,什么时候GHC自己根据GADTs类型构造函数上的约束来解决它?

共有1个答案

包阳成
2023-03-14

使用GADT的全部意义在于,您希望约束显示在bar的签名中,而不是foo。如果您不想这样做,那么可以使用普通的旧newtype:

newtype MyAdt = Sample a

foo :: Show a => MyAdt a -> String
foo (Sample a) = show a

bar :: a -> MyAdt a
bar = Sample

foobar中使用约束显然不能起作用,因为这样您就可以例如。

showFunction :: (Integer -> Integer) -> String
showFunction = foo . bar
 类似资料:
  • 在过去一周左右的时间里,我一直在为Scala开发一个类型化、索引化的数组特性。我希望将该特征作为类型类提供,并允许库用户以他们喜欢的方式实现它。下面是一个示例,使用列表的列表来实现2D数组类型类: 这一切看起来都很好。我遇到的困难是,我希望将索引类型约束为一个已批准类型的列表(用户可以更改)。由于程序不是所有已批准类型的原始所有者,所以我想用一个typeclass来表示这些已批准类型,并让已批准类

  • 我有一系列复杂的类型级别函数,它们的计算结果如下: 显然,在这种情况下,这个表达式是一个。更一般地说,我们可以说: 有没有办法教GHC推断这一点? 编辑:@chi指出,在某些情况下,GADT可以解决这一问题,但我的特殊情况是: 然后 不能被访问,但是也许GHC应该能够推断出

  • 销关节 cpPinJoint *cpPinJointAlloc(void) cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2) cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1,

  • 泛型的类型约束 swapTwoValues(_:_:)函数和Stack类型可以用于任意类型. 但是, 有时在用于泛型函数的类型和泛型类型上, 强制其遵循特定的类型约束很有用. 类型约束指出一个类型形式参数必须继承自特定类, 或者遵循一个特定的协议、组合协议. 例如, Swift的Dictionary类型在可以用于字典中键的类型上设置了一个限制. 如字典中描述的一样,字典键的类型必须是可哈希的. 也

  • Haskell是一种函数语言,它是严格类型化的,Haskell编译器在编译时知道整个应用程序中使用的数据类型。 1. 内置类型类 在Haskell中,每个语句都被视为数学表达式,并且此表达式的类别称为类型()。可以说是在编译时使用的表达式的数据类型。 要了解有关类型的更多信息,可以使用命令。以通用的方式可以将类型视为值,而可以将类型类视为一组相似类型的类型。在本章中,我们将学习不同的内置类型。 2

  • 此代码只是使用中间的来删除重复项,其中元素之间的相等性是根据提供的比较器定义的。 让我们给局部类型推断一个机会吧,我(天真地)想...于是我将上面的代码改为: 这对我来说是有意义的,因为的类型可以从的类型推断出来,或者我是这么想的。但是,修改后的代码无法编译,并生成以下错误: 注意1:编译代码的一种方法是将返回类型更改为。不过,那是一套很难用的... 注意2:另一种方法是在比较器中不使用逆变,但我