I just noticed you can do this:

{-# LANGUAGE GADTs, RankNTypes #-} module Data.Foldable.Mono((*$*)) where import Data.MonoTraversable(Element, MonoFoldable(..)) -- ^ from the mono-traversable package (*$*) :: MonoFoldable mono => (forall t. Foldable t => t (Element mono) -> a) -> mono -> a f *$* o = f (Foldabilized o) data Foldabilized a where Foldabilized :: MonoFoldable mono => mono -> Foldabilized (Element mono) instance Foldable Foldabilized where foldr f z (Foldabilized o) = ofoldr f z o -- (Similar implementations for the other methods can be included -- here for efficiency.) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 {-# LANGUAGE GADTs, RankNTypes #-} module Data . Foldable . Mono ( ( * $ * ) ) where import Data.MonoTraversable(Element, MonoFoldable ( . . ) ) -- ^ from the mono-traversable package ( * $ * ) :: MonoFoldable mono = > ( forall t . Foldable t = > t ( Element mono ) -> a ) -> mono -> a f * $ * o = f ( Foldabilized o ) data Foldabilized a where Foldabilized :: MonoFoldable mono = > mono -> Foldabilized ( Element mono ) instance Foldable Foldabilized where foldr f z ( Foldabilized o ) = ofoldr f z o -- (Similar implementations for the other methods can be included -- here for efficiency.)

And then use it like this:

import Data.Foldable.Mono import qualified Data.Text.Lazy as T testText = T.pack "foo quux bar" example1 = maximum *$* testText -- ^ equals 'x' example2 = mapM_ print *$* testText -- ^ prints "'f'

'o'

'o'

..." 1 2 3 4 5 6 7 8 import Data.Foldable.Mono import qualified Data . Text . Lazy as T testText = T . pack "foo quux bar" example1 = maximum * $ * testText -- ^ equals 'x' example2 = mapM_ print * $ * testText -- ^ prints "'f'

'o'

'o'

..."

Notice that those are the polymorphic Foldable functions maximum and mapM_ , not Text -specific functions. I don’t know if this has any real-world applications, but it’s kind of neat…

Update: As pointed out by lfairy on Reddit, the FMList type works kind of like this.