Why Data.Set (containers) doesn't have Functor and Monad instance?


#1

Data.Set

It have map, singleton and unions seem like should be enough to from a monad.


#2

For efficiency reasons, Set has an Ord constraint, but Functor has not!

On top of that, even if the Ord constraint were not a problem, Set would still not satisfy

fmap (f . g)  ==  fmap f . fmap g

for some peculiar Eq instances. E.g.:

import Data.Set as S

newtype A = A Double
    deriving Show

instance Eq A where
    (A a) == (A b) = round a == round b

instance Ord A where
    (A a) <= (A b) = a <= b

prova :: Set A
prova = fromList [A 11, A 12]

main = do
        print (S.map f . S.map g $ prova)
        print (S.map (f . g) prova)
        putStrLn "Ooops!"
    where
        f (A n) = A (n * 10)
        g (A n) = A (n / 10)

#3

I hope that they make the “customary” properties of Eq and Ord proper laws in Haskell2020.


#4

if you know the consequences you can write your own orphan-instances for Functor etc.
but be warned that they may explode in your face if the optimizer looks at them wrong as @f-a has already posted.

But most of the time you want to use mapMonotonic anyway as it is O(n) instead of O(n*log(n)).
Your call - but in any case there should be no “default”, because there is no unique emphasized text"correct" instance.