snoyberg/mono-traversable's README notes
[MonoFoldable is the same] as Foldable, but also operates over monomorphic containers.
Please give an example where Foldable does not operate over monomorphic containers.
Text is intuitively a container, however it is not polymorphic. Hence
Prelude> Data.Foldable.foldr ((:) . fromEnum) [] (Data.Text.pack "blub")
<interactive>:8:28: error:
• Couldn't match expected type ‘[a0]’
with actual type ‘Data.Text.Internal.Text’
• In the third argument of ‘foldr’, namely
‘(Data.Text.pack "blub")’
In the expression:
foldr ((:) . fromEnum) [] (Data.Text.pack "blub")
In an equation for ‘it’:
it = foldr ((:) . fromEnum) [] (Data.Text.pack "blub")
OTOH,
Prelude> Data.MonoTraversable.ofoldr ((:) . fromEnum) [] (Data.Text.pack "blub")
[98,108,117,98]
A Foldable has kind * -> *. Lists, trees, basically anything that can take another type for their element type has that kind. Any instance of Foldable must be a type constructor , not a type , since the class is defined as
class Foldable (t :: * -> *) where
foldMap :: Monoid m => (a -> m) -> t a -> m
-- ^ ^
However, Text, ByteString and other types are clearly a collection of some underlying element type, yet their kind is *. They aren't type constructors, they are already types. They don't fit foldMap's type:
listLength :: Text -> Int
listLength = getSum . foldMap (const (Sum 1))
textLength :: Text -> Int
textLength = foldMap magic -- will never compile, for no magic
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With