使用`Foldable`类型约束折叠类型签名

时间:2018-03-01 19:44:31

标签: haskell fold type-signature

在我的GHCi foldrfoldl上有这个签名:

Prelude> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
Prelude> :t foldl
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b

折叠的替代类型签名之间有什么区别,特别是t a部分?

fr :: (a -> b -> b) -> b -> [a] -> b
fl :: (b -> a -> b) -> b -> [a] -> b

1 个答案:

答案 0 :(得分:2)

类型类Foldable除了foldl之外还定义了许多函数。

class Foldable t where
    foldMap :: Monoid m => t m -> m
    foldr :: (a -> b -> b) -> b -> t a -> b
    foldl :: (b -> a -> b) -> b -> t a -> b
    -- ...

我们可以通过为类型定义至少Foldablet来为类型构造函数foldMap定义{em>实例 foldr。 (foldl有一些默认定义,所以只要提供最小定义,就可以获得" free"。

instance Foldable [] where
    foldr f b [] = b
    foldr f b (x:xs) = f x : foldr f b xs

instance Foldable Maybe where
    foldr f b Nothing = b
    foldr f b (Just a) = f b a

类型签名中的t只是意味着只要类型构造函数为其定义了Foldable实例,就可以使用foldl来获取相应类型的值。例如:

Prelude> foldl (+) 0 [1,2,3]
6
Prelude> foldl (+) 0 []
0
Prelude> foldl (+) 0 Nothing
0
Prelude> foldl (+) 0 (Just 3)
3

在前两种情况下,我们使用[]实例,因为与t a对应的参数是列表,这意味着t统一 {{1写的[]。在后两个中,我们使用t ~ []实例,因为与Maybe对应的参数是t a值,因此Maybe