如何在Haskell中创建一个nullary数据构造函数返回True为null

wsa*_*eem 2 null haskell

我说有一个代数数据类型

data Tree a = Node a (Tree a) (Tree a) | Empty

我想null返回TrueEmpty节点; False除此以外.

例如,

> tree = Empty
> null tree 
Run Code Online (Sandbox Code Playgroud)

现在,这会产生以下错误.

<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
Run Code Online (Sandbox Code Playgroud)

请注意,null不会返回TrueNothing.

> null Nothing
True
Run Code Online (Sandbox Code Playgroud)

bas*_*nry 9

null需要一个实例Foldable:null :: Foldable t => t a -> Bool

创建Foldablefor 的实例的最简单方法Tree a是:

{-# LANGUAGE DeriveFoldable #-}

data Tree a = Node a (Tree a) (Tree a) | Empty deriving Foldable
Run Code Online (Sandbox Code Playgroud)

或者在GHCi:

? > :set -XDeriveFoldable
? > data Tree a = Node a (Tree a) (Tree a) | Empty deriving Foldable
? > null Empty
True
? > null (Node 1 Empty Empty)
False
Run Code Online (Sandbox Code Playgroud)

:之所以null回归TrueNothing是因为Maybe有一个实例Foldable.

漫长的道路:

而不是使用Haskell的神奇扩展来获取快捷方式,您可以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)
Run Code Online (Sandbox Code Playgroud)

  • @wsaleem`null`调用`foldr`,其中`True`为默认值,`const False`为折叠函数.因此,如果折叠函数至少应用一次,我们得到"假",否则我们得到"真".所以问题就变成了"派生可折叠"如何生成`foldr`的定义.对此的回答将是:它在`a`类型的每个字段上调用折叠函数,并在`tree a`类型的每个字段上重复(或者更确切地说是任何类型`fa`,其中` f`是`Foldable`的一个例子. (3认同)