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.)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'\n'o'\n'o'\n..."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.