最新GHC中不推荐使用的DatatypeContexts:为什么?


70

我只是在进行一些Haskell开发,并在新版本的GHC上重新编译了一些旧代码:

The Glorious Glasgow Haskell Compilation System, version 7.2.1

当我这样做时,我收到以下错误:

警告:-XDatatypeContexts已过时:普遍认为它不适合使用,已从Haskell语言中删除。

当您使用以下格式的代码时,将显示该消息:

data Ord a => MyType a
    = ConstructorOne a
    | ConstructorTwo a a

我的问题是:为什么首先不赞成使用此功能,而我应该怎么做才能实现相同或相似的功能?


13
只需删除上下文,您的代码仍然可以使用。
2011

如果cabal install <package>尝试时遇到相关错误,请尝试cabal install --ghc-option '-XDataTypeContexts' <package>
ntc2

@ ntc2作为一个答案,也许命令应该包含-XDatatypeContexts小写字母t
Ludovic Kuty

Answers:


100

不推荐使用它因为它的功能不当,并且实际上没有任何有用的功能!它所做的只是在其他位置施加了很多额外的约束。特别是,当在这种类型上进行模式匹配时,您将被迫添加一个约束,而不是(如人们最初希望的那样)基于对一个上下文的访问,而该知识必须已经可以构造该值首先。

实际上,“替换”可以用另一种方式为您跟踪已知的上下文,而是使用GADT样式的声明

data MyType a where
    ConstructorOne :: Ord a => a -> MyType a
    ConstructorTwo :: Ord a => a -> a -> MyType a

一般而言,GADT在许多其他方式上也更加灵活,但是在这种特殊情况下,发生的事情是创建值需要Ord约束,然后将约束与值一起携带,并且构造函数上的模式匹配会将其撤回。因此,您甚至不需要使用它的函数上的上下文,因为您知道借助期望类型的东西MyType a,您将获得Ord a约束。


最后一句似乎不太清楚-从GADT构造函数中提取的内容不是约束,而是满足约束的实例。
dfeuer 2015年

1
但是,如果构造函数太多,Ord a难道每个函数都不会重复冗长吗?
造假

3
@fakedrake我的意思是无论如何这都不应该经常出现。您几乎总是不想限制自己的类型。为什么是它使得它不可能让你的类型的一个例子FunctorFoldableTraversableApplicativeMonadAlternativeMonadPlusArrow等。
分号

GADT非常好,因为在某些情况下我可以使用一些受限制的构造函数,并且我发现在某些情况下这很有用。感谢你的回答。
Paul Stelian

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.