Haskell中foldr实现出现Show实例缺失错误求助
自定义Tree的Foldable实例Show约束错误解析
错误原因
你写的foldr实现里用了trace (show x),这里x的类型是a(Tree的元素类型),show函数要求a必须是Show类型类的实例。但Foldable类型类规定的foldr方法签名是没有Show a约束的——Foldable是通用的折叠接口,设计目标是支持任意类型的容器元素,不管元素能不能被打印。
编译器检测到你在foldr里偷偷加了Show a的要求,但没有在类型签名里声明,所以抛出这个错误。
解决办法
临时调试方案(仅用于测试)
如果只是为了调试时打印元素,可以给当前的foldr显式加上Show a约束,注意这会让你的Foldable实例不符合标准接口,只适合调试阶段用:
import Debug.Trace data Tree a = Nil | Branch (Tree a) a (Tree a) deriving (Eq, Show) instance Foldable Tree where foldr :: Show a => (a -> b -> b) -> b -> Tree a -> b foldr _ ini Nil = ini foldr f ini (Branch l x r) = trace (show x) (foldr f (f x (foldr f ini r)) l)
规范解决方案
正式代码里不要在Foldable实例中加入调试代码,保持接口的通用性。如果需要调试,要么在测试代码中给Tree的元素指定Show实例(比如用Tree Int这种自带Show的类型),要么把调试逻辑移到实例外面。
比如测试时可以这样写:
testTree :: Tree Int testTree = Branch (Branch Nil 1 Nil) 2 (Branch Nil 3 Nil) main = print $ foldr (+) 0 testTree
此时因为Int是Show实例,trace (show x)就能正常工作,同时Foldable实例本身不需要加额外约束。
内容的提问来源于stack exchange,提问作者mikeeeeeee
相关产品推荐
相关产品推荐

