我正在研究这个Data.Text all函数,做了一些简单的例子并将它们结合起来,这时我发现 GHCI 中这段简单代码的评估结果为 True,问题是为什么?

import qualified Data.Text  as T
T.all C.isSymbol (T.filter C.isNumber (T.pack "asad"))
GHCI => True

我感到困惑,因为评价:

(T.filter C.isNumber (T.pack "asad"))
GHCI => ""

这是一个错误吗?还是设计使然?

2

  • 1
    其他语言的相关问题:


    – 


  • 在数学中,这被称为


    – 


最佳答案
4

您可能还记得高中数学中学习过和式和积,比如。您可能还记得,当和式没有任何项时,我们称其为 0,而当积式没有任何项时,我们称其为 1。但您是否了解过我们为什么选择这些定义?

在 Haskell 中,我们可以看到基础库在其sum和的定义中反映了这些事实product

> sum []
0
> product []
1

这些选择之所以好,原因之一是以下特性:如果我们有一个包含一堆项的和,我们可以将这些项任意分成两组,分别求和,然后将结果相加。使用 Haskell 启发的语法,我们可以表达类似的特性,如下所示:

forall xs ys, sum xs + sum ys = sum (xs ++ ys)

此属性的一个有趣之处是,它迫使我们定义空列表的总和——它必须为 0!

sum [] + sum ys = sum ([] ++ ys) = sum ys

现在只需sum ys从两边减去。产品的类似属性,

forall xs ys, product xs * product ys = product (xs ++ ys)

迫使我们选择 1:

product [] * product ys = product ([] ++ ys) = product ys

是否有类似的属性all?有!如果一个列表的所有元素都满足一个谓词,而另一个列表的所有元素都满足同一个谓词,那么当你连接这两个列表时,所有元素仍然满足该谓词。

forall p xs ys, all p xs && all p ys = all p (xs ++ ys)

通过与上述类似的推理,我们可以很好地了解all应该对空列表做什么:

forall p ys, all p [] && all p ys = all p ([] ++ ys) = all p ys

验证这个等式最简单的方法all p [] && X = X就是选择all p [] = True——这正是我们所做的。

如果你想练习这种思维,你能想到这样的属性吗any?应该怎么any p []做才能验证该属性?假设我定义:

lcms :: Integral a => [a] -> a
lcms (x:xs) = lcm x (lcms xs)

在哪里

-- lcm x y is the smallest positive integer that both x and y divide.
lcm :: Integral a => a -> a -> a 

我应该选择什么作为答案lcms []

0

为什么它会返回除 之外的任何内容True?它检查的所有零字符都是符号。它们也都是数字。它们都是大写字母。它们都是小写字母。它们都是西里尔字母。它们都是表情符号。

这些语句并不十分有趣。事实上,它们有些微不足道。但它们都是正确的。鉴于它们是正确的,函数返回 就显得非常粗鲁了False

集上的所有元素都是真的。事实上,“所有生活在太阳上的马都是蓝色的”是一个真命题,没有生活在太阳上的马,所以我们可以说所有马都是蓝色的。这就是的工作原理,对于列表也是如此,例如:

ghci> all (>6) []
True

你从一串字母(az)开始,然后你因为过滤器而过滤掉所有字符isNumber,然后你问剩下的所有字符(没有字符)是否都是符号,因为没有这样的字符,事实确实如此。

all被解释为“集合中没有反例”。如果集合为空,则不可能有反例,因此all返回 true。

all按照或来实施可以帮助建立这一点的直觉。