Haskell定义BST数据类型报Illegal datatype context错误如何解决?
报错原因
- 在 Haskell 2010 及后续版本中,数据类型上下文(Data type context) 语法默认被禁用,你写在
data定义前的(Ord a, Show a, Read a) =>约束就属于这类语法。 - 该语法最初设计的目的是为所有操作BST的场景自动带上类型约束,但实际使用中会引入大量不必要的约束,哪怕你只是做遍历树、统计节点数这类不需要比较、打印值的操作,也需要强制携带约束,因此被社区弃用,对应的
DatatypeContexts扩展属于废弃特性,默认不会开启,因此编译器抛出非法语法错误。
解决方法
分为两种方案,优先推荐第二种:
- (不推荐,仅做兼容用)开启废弃扩展保留原有写法
在代码文件的最顶部添加编译指令手动开启扩展:
{-# LANGUAGE DatatypeContexts #-}
该特性随时可能在后续GHC版本中被移除,不建议长期使用。
- (推荐)将约束移动到需要的函数签名上
删除数据类型定义上的约束,只保留结构定义:
data BST a = Void | Node { val :: a , left , right :: BST a } deriving ( Eq , Ord , Read , Show )
后续写BST的操作函数时,只给需要对应约束的函数加限制即可:
- 比如做插入、查找需要比较值的函数,签名加上
Ord a约束:
insert :: Ord a => a -> BST a -> BST a -- 函数实现
- 比如需要打印节点值的遍历函数,签名加上
Show a约束:
printBST :: Show a => BST a -> IO () -- 函数实现
这种写法更灵活,不会给不需要约束的操作引入额外限制,也是当前Haskell社区的标准实践。
内容的提问来源于stack exchange,提问作者Dacleoz
相关产品推荐
相关产品推荐

