为什么不能把类型签名放在Haskell的示例声明中?

dbf7pr2w  于 2023-03-08  发布在  其他
关注(0)|答案(6)|浏览(141)

我喜欢在我的代码中为所有顶层定义放置类型签名。然而,在示例声明中放置类型签名似乎是不被允许的,如果我放置了一个类型签名,我会从GHC得到一个“错位的类型签名”错误。为什么会这样呢?为什么GHC不能检查类型签名是否与它所期望的相同,如果不相同则拒绝(或警告)?

06odsfpq

06odsfpq1#

你可以使用[the new] -XInstanceSigs为示例添加类型签名,这对于将类型变量带入作用域特别有用。你可以在官方文档中找到更多信息。

tez616oj

tez616oj2#

如果您真的需要类型声明,可以在示例体之外单独创建函数。

class Class a where
    f1 :: a -> a

instance Class Foo where
    f1 = foo_f1

--monomorphic version of f1 for Foo:
foo_f1 :: Foo -> Foo
foo_f1 = ...
q5lcpyga

q5lcpyga3#

这里的大多数其他答案都很老了......现在有一个语言扩展:
把下面的内容贴在你的文件的顶部:

{-# Language InstanceSigs #-}
lf3rwulv

lf3rwulv4#

因为签名是类定义的一部分,所以示例声明中的类型签名是重复签名,我认为原则上允许重复签名没有问题,但一般情况下允许重复签名没有好处。而且不允许它们更简单,所以语言定义说每个实体最多只能有一个类型签名。在示例声明中也允许签名的特性还没有被要求太多,所以没有扩展允许它。如果你真的想这样,你可以在GHC trac上提出一个特性请求。如果它得到足够的关注,它可能会被实现(但我不希望要求很高)。

wecizke3

wecizke35#

在任何情况下,类型都是冗余的,通常人们都希望避免冗余。在Frege中,仍然允许为示例成员编写类型签名。它们被检查,然后被丢弃。当然,立即禁止它们更容易。

rkkpypqq

rkkpypqq6#

GHC 9.2.1以来,在示例声明中允许类型签名在默认情况下是启用的
这源于支持GHC2021的GHC 9.2.1,它默认启用一些扩展,其中包括InstanceSigs扩展。
以下是文档中的示例:

instance Eq a => Eq (T a) where
   (==) :: forall b. b -> b -> Bool
   (==) x y = True

注意,示例中的类型签名在大多数情况下是多余的。文档提到了添加它们的可能动机:

  • 使用类型检查器确认推断的类型与程序员期望的匹配(这是用户发布原始问题的动机)
  • 作为记录代码的一种方式
  • 将作用域类型变量带入作用域

在Haskell示例声明中允许类型签名的历史记录

这个特性源于StackOverflow问题。
发布问题的用户创建了一个问题票证,与他在2011年提出的问题相同。第二天,Dan Burton也created a ticket,第一张票作为复制品被关闭。第二天,Simon佩顿Jones 插话说他自己也希望有这种可能性。他在同一天草拟了实现方案,并在七天后制作了the commit。该扩展是GHC 7.6新增的,在2021年10月发布的GHC 9.2.1中默认启用。
注意:* 纯脚本 * added the extension in 2017 .

相关问题