1

我正在尝试创建一个空列表,然后确认它是空的,以便稍后我可以将元素插入其中。

我试图简单地将函数分配给一个空列表,但是当我尝试确认它是空的时,我在函数异常中得到了一个非穷举模式。

这是我到目前为止所拥有的。

emptyList::Ord a => [(a,b)]
emptyList = []

isEmpty::Ord a => [(a,b)] -> Bool
isEmpty[(a,b)] = null [undefined, undefined]

我试图得到类似 isEmpty emptyList True 我想我的问题是,如何根据给定的类型确认列表为空?

4

1 回答 1

2

我认为您将类型 ( [(a,b)]) 与模式混淆了。在你的isEmpty函数中,你写:

isEmpty::Ord a => [(a,b)] -> Bool
isEmpty [(a,b)] = null [undefined, undefined]

但这并不意味着您要匹配type [(a,b)]的列表。你已经在你的类型签名中说过了。你[(a,b)]在第二行,意味着你定义了一个模式。该模式说您只匹配包含一个元素的列表一个 2 元组,a该元组的第一项,该元组b的第二项。

如果您随后将一个空列表或包含两个或多个元素的列表传递给它,则该模式将不匹配,因此会引发错误。

如果你想匹配任何列表,你可以简单地使用一个变量:

isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty ls = null ls

因此,这里isEmptynull使用该变量调用。我们可以在这里执行η-reduction,并写成:

isEmpty :: Ord a => [(a,b)] -> Bool
isEmpty = null

完全没有必要将自己限制为仅具有 2 元组的列表,其中这些元组的第一项具有类型类成员的Ord类型,但是,我们可以让它与任何列表一起使用。所以我们可以将类型概括为:

isEmpty :: [a] -> Bool
isEmpty = null

事实上null可以操作任何Foldable,因为它有类型null :: Foldable f => f a -> Bool

有了上面的函数定义,就不需要自己实现了isEmpty,直接调用就可以了null emptyList

于 2019-10-13T08:32:41.267 回答