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
(*$* o = f (Foldabilized o)
f
data Foldabilized a where
Foldabilized :: MonoFoldable mono =>
-> Foldabilized (Element mono)
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
= T.pack "foo quux bar"
testText = maximum *$* testText
example1 -- ^ equals 'x'
= mapM_ print *$* testText
example2 -- ^ 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.