以下是《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/