【问题标题】:Fold type signature with `Foldable` type constraint具有“可折叠”类型约束的折叠类型签名
【发布时间】:2018-03-01 19:44:30
【问题描述】:

在我的GHCifoldrfoldl 上有这个签名:

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

【问题讨论】:

  • 你是在问t a 是什么意思吗?你明白Foldable t => 部分是什么意思吗?
  • 不,我不知道。
  • 昨天刚刚问过的stackoverflow.com/q/49036437/1126841 的近似副本。

标签: haskell fold type-signature


【解决方案1】:

类型类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
    -- ...

我们可以通过至少为类型定义foldMapfoldr 来为类型构造函数t 定义Foldable实例。 (foldl 对其他一些定义有默认定义,因此只要您提供最低定义,您就可以“免费”获得它)。

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[]统一,写作t ~ []。后两个我们使用Maybe实例,因为t a对应的参数是Maybe的值,所以t ~ Maybe

【讨论】:

  • 我不知道您可以为 [] a 这样的列表编写类型签名,而不是 [a]。这类似于Foldable吗?
  • [a] 只是[] a 的语法糖(我认为[] 是特殊情况下的类型构造函数的有效名称)。 Foldable 只是各种折叠的概括,允许您使用 foldl 等。在列表以外的容器类型上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2016-05-17
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
  • 2015-09-23
相关资源
最近更新 更多