如何使用函数的幺半群实例?

How do I use a monoid instance of a function?

今天我试图通过 monoid 类型类减少函数列表,但出于某种原因,生成的函数期望它的参数是 Monoid 的一个实例。

GHCI 告诉我 mconcat [id, id, id, id] 的类型是 Monoid a => a -> a。但我希望它是 a -> a.

发生了什么事?

您正在使用此实例:

instance Monoid b => Monoid (a -> b) where
    mempty _ = mempty
    mappend f g x = f x `mappend` g x

更通用,因为它不需要自同态(即 a -> a)。要获得您期望的实例,您可以将函数包装在 Endo:

appEndo (mconcat [Endo id, Endo id, Endo id, Endo id])

appEndo $ mconcat $ fmap Endo [id, id, id, id]