haskell - FoldMap 采用错误类型的参数?

标签 haskell monoids

以下是《Learn You a Haskell》中的一些示例:

import qualified Data.Foldable as F

data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)  

instance F.Foldable Tree where  
    foldMap f Empty = mempty  
    foldMap f (Node x l r) = F.foldMap f l `mappend`  
                             f x           `mappend`  
                             F.foldMap f r  

testTree = Node 5  
            (Node 3  
                (Node 1 Empty Empty)  
                (Node 6 Empty Empty)  
            )  
            (Node 9  
                (Node 8 Empty Empty)  
                (Node 10 Empty Empty)  
            )  

测试它:

> let z = F.foldMap (+) testTree
> :t F.foldMap
F.foldMap :: (Monoid m, F.Foldable t) => (a -> m) -> t a -> m
> :t (+)
(+) :: Num a => a -> a -> a
> :t z
z :: (Monoid a, Num a) => a -> a

F.foldable 的第一个参数是一个返回 Monoid 的函数,但 Num 不是 Monoid 的子类,所以 (+) 在这里肯定不合格?但从测试来看,它似乎很合适。

z在这里有点神秘,它应该是一个Monoid,但它具体是什么?

最佳答案

“Num a =>”是一个类型类约束,它指示 (+) 的参数和结果必须至少是类型类“Num”的成员,但它们可以是完美成员也可以是任何其他类型类(在本例中为 Monoid)。

对于 z,有一些标准类型可以满足这些约束(同时是 Num 和 Monoid 的一部分)。它们是 Sum 和 Product,在 Data.Monoid 中定义。

为了回答您的问题,求和树或乘积树将通过类型检查并工作,您定义为类型类 Num 和 Monoid 一部分的任何其他类型也将如此。

关于haskell - FoldMap 采用错误类型的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29334571/

相关文章:

scala - 如果数据结构是可折叠的,它是幺半群吗?

haskell - 快照框架 : Compiled splices and processing forms with digestive functors

scala - Scala 的列表是否在连接运算符下形成了幺半群?

Haskell:如何为依赖参数的东西编写 `Monoid` 实例

haskell - 将函数组合成一个返回元组的函数

scala - 幺半群同态和同构

haskell - Last 是一个自由幺半群吗?

haskell - where 子句中的类型孔不起作用

Haskell - 一些,很多实现

为有限列表使用 foldl' 实现 concatMap 的性能提升?