2012-07-14 23 views
34

me gustaría para ordenar por una propiedad y luego por otra (si es la primera propiedad es lo mismo).componiendo dos funciones de comparación?

Cuál es la forma idiomática en Haskell de componer dos funciones de comparación, es decir, una función utilizada con sortBy?

Dada

f :: Ord a => a -> a -> Ordering 
g :: Ord a => a -> a -> Ordering 

componer f y g habría Rendimiento:

h x y = case v of 
      EQ -> g x y 
      otherwise -> v 
     where v = f x y 
+21

Uso 'Data.Monoid', puede obtener:' fxy \ 'mappend \' gxy'. – Vitus

Respuesta

51

vitus señala la instancia muy fresco de Monoid para Ordering. Si se combina con la instancia instance Monoid b => Monoid (a -> b) resulta que la función de su composición es simplemente (preparémonos):

mappend 

Hay que ver:

Prelude Data.Monoid> let f a b = EQ 
Prelude Data.Monoid> let g a b = LT 
Prelude Data.Monoid> :t f `mappend` g 
f `mappend` g :: t -> t1 -> Ordering 
Prelude Data.Monoid> (f `mappend` g) undefined undefined 
LT 
Prelude Data.Monoid> let f a b = GT 
Prelude Data.Monoid> (f `mappend` g) undefined undefined 
GT 

+1 para abstracciones potentes y sencillas

+4

Woah ... eso es increíble. – huon

+0

Sabía que Haskell tenía que tener una solución elegante para esto :) Gracias por explicarlo de manera clara y concisa. –

+0

Esto es brillante. Para ordenar una lista de pares: 'sortBy (comparando fst <> comparando snd)' – dcastro

Cuestiones relacionadas