我有一个代数数据类型,比如说
data Tree a = Node a (Tree a) (Tree a) | Empty
我希望null
为True
节点返回Empty
;否则False
。
例如,
> tree = Empty
> null tree
现在,这会产生以下错误。
<interactive>:261:1: error:
• No instance for (Foldable Tree) arising from a use of ‘null’
• In the expression: null tree
In an equation for ‘it’: it = null tree
请注意,null
确实会为True
返回Nothing
。
> null Nothing
True
答案 0 :(得分:9)
null
需要Foldable
:null :: Foldable t => t a -> Bool
为Foldable
创建Tree a
实例的最简单方法是:
{-# LANGUAGE DeriveFoldable #-}
data Tree a = Node a (Tree a) (Tree a) | Empty deriving Foldable
或GHCi
:
λ > :set -XDeriveFoldable
λ > data Tree a = Node a (Tree a) (Tree a) | Empty deriving Foldable
λ > null Empty
True
λ > null (Node 1 Empty Empty)
False
注意:null
将True
返回Nothing
的原因是因为Maybe
的实例为Foldable
。
很长的路:
而不是使用Haskell的魔法扩展程序获取快捷方式,您可以按照here解释手动编写Foldable
实例,它可以归结为:
data Tree a = Node a (Tree a) (Tree a) | Empty
instance Foldable Tree where
-- The minimal definition is "foldMap" or "foldr", I'm choosing "foldr"
-- foldr :: (a -> b -> b) -> b -> Tree a -> b
foldr _ b Empty = b
foldr f b (Node a left right) = f a (foldr f (foldr f b right) left)