Haskell 中的任何类型?

Type of any in Haskell?

我最近开始尝试通过阅读 LearnYouAHaskell 和互联网上的随机文章来学习 Haskell。

我很难理解更复杂的函数类型。

一些我理解的例子。

> :t map  
map :: (a -> b) -> [a] -> [b]

它接受一个函数(它接受 a 并给出 b,即 a 和 b 可以是不同的类型)和一个 a 的列表,return一个 b 的列表。

> :t fst  
fst :: (a, b) -> a

接收 2 个元素的元组(允许不同类型),return第一个元素。

> :t any  

更高层次的理解any。它接受一个函数和一个列表,如果列表中的任何条目 return 对于该特定函数为真,则 return 为真。我也在 Python 和 JavaScript 中使用过它。

问题

t a不代表谓词和列表。正如您之前已经正确指出的那样,(a -> Bool) 是谓词。 t a 仅表示列表,但它不一定是列表(这就是为什么它是 t a 而不是 [a] 的原因)。 t 可以是任何 Foldable,所以它可以是 [],但它也可以是其他集合类型或 Maybe.

any :: Foldable t => (a -> Bool) -> t a -> Bool

这里 Foldable t 的意思是,t 是 class Foldable.

类型的一个实例

Foldable 是类型 class 如果类型 t 是类型 class 的实例 Foldable 我们从 t a 签名的一部分或者从类型 class Foldable 的定义来看,t 实际上是一个类型构造器。

所以 t a 是一个类型,因此 t a -> Bool 是一个函数,它将类型 t a 的值映射到 Bool。这个函数将是闭包,它将 将谓词应用于 t a 类型值的每个 "element",直到它找到一个在谓词下产生 True 的元素,或者找不到这样的元素返回 [=25] =] 或 False 在各自的情况下。 (实际实施可能有很大不同。)

例如 [] 是 class Foldable 类型的一个实例,因此 t a 可能是一个列表。在这种情况下,我们也可以写成 [a] 而不是 [] a.

但是还有其他类型的构造函数,可以是Foldable的实例,例如一些树。

注意 until recently, the signature was actually

可能会有所帮助
any :: (a -> Bool) -> [a] -> Bool

这在 the Foldable Traversable in Prelude proposal: now the container of values need not be a list, but can as well be e.g. an array 期间被推广:

Prelude> import qualified Data.Vector as Arr
Prelude Arr> :set -XOverloadedLists
Prelude Arr> let a = [1,2,3] :: Arr.Vector Int
Prelude Arr> any (>2) a
True

t a 没有被 -> 分隔,因为 t a 是可折叠的实例,例如:列表 a 或树 a。让我们暂时回到 map。您提供的版本专门用于列表;一个更通用的版本(作为历史的偶然,在 Haskell 的大多数版本中称为 fmap)具有类型 fmap :: Functor f => (a->b) -> f a -> f b。您在此签名中的输入列表在哪里?这是 f a。现在,返回 anyt a 是第二个参数,您要折叠的 Foldable 实例,列表或树或其他任何东西。

您会读到 Haskell 中的所有函数实际上只有 1 个参数,我们在这里看到了这一点。 any 接受它的第一个参数(谓词)和 returns 接受可折叠(列表、树等)的函数和 returns 一个 Bool

类型签名是函数的标记名称,指示要处理的类型以及如何部分应用该函数。

Foldable t => (a -> Bool) -> t a -> Bool

Foldable t 首先说 any 函数可以使用任何数据类型,它是可折叠类型 class.

的实例

第一个参数 (a -> Bool) 显然是一个函数,它从我们的可折叠数据类型中获取单个元素 (a) 和 returns 一个 Bool 类型值。是JavaScript中.some(callback)的回调。当您将此参数应用于 any 时,您将返回一个类型为;

的函数

t a -> Bool

现在我们只剩下一个函数,它只接受一个参数和 returns 一个 Bool 类型(TrueFalse)值。同样,t a 是一种数据类型,它是可折叠类型 class 的成员。它可以是 [],但也可以是 Tree,前提是数据类型具有在 Foldable 实例下定义的 foldMap 函数。它是 JavaScript 的 myArr.some(callback) 中的 myArr 部分,只是它不必是数组。