Reputation: 41909
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.
Upvotes: 4
Views: 278
Reputation: 23135
ByteString
and Text
, which can only contain Word8
and Char
respectively. Also unboxed arrays have a restriction on their data type so can't be directly made instances of Foldable
.
Note however you can trivially make a Monofoldable
into a Foldable
just by wrapping it appropriately. My package make-monofoldable-foldable
does that for you, so for example if you need to pass a ByteString
to a function that expects a Foldable
you can just wrap it with WrappedMonoFoldable
and then pass it in.
Upvotes: 1
Reputation: 105886
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
Upvotes: 4
Reputation: 23502
I think what's meant here is, that usually when talking about Foldable
we mean the higher-kinded polymorphic version. I.e. List
is a Foldable
for all a
. So Foldable
works on types * -> * (also called type constructors).
The MonoFoldable
type class works on actual types instead. So for example we could write an instance of MonoFoldable
for something like Text
.
Upvotes: 1
Reputation: 120711
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]
Upvotes: 7