2015-07-23 3 views
2

есть способ использовать шаблоны шаблоны для конструкторов типов, чтобы сделать этот уродливый код короче:сравнить содержимое типа Либо

eitherCompare (Left a) (Left b) = compare a b 
eitherCompare (Left a) (Right b) = compare a b 
eitherCompare (Right a) (Left b) = compare a b 
eitherCompare (Right a) (Right b) = compare a b 

что-то вроде (не компилируется)

eitherCompare :: Ord a => Either a a -> Either a a -> Ordering 
eitherCompare (_ a) (_ b) = compare a b 

или какой-то другой метод?

ответ

5

Вы не можете сделать это с помощью сопоставления с образцом, но вы можете упростить код, используя вспомогательную функцию:

eitherCompare x y = compare (fromEither x) (fromEither y) 
where fromEither (Left a) = a 
     fromEither (Right a) = a 
+9

Более простое определение '' fromEither' является fromEither = либо идентификатор id'. – amalloy

+0

Это, вероятно, слишком придирчиво, что даже стоит упомянуть, но это не совсем эквивалентно исходной версии (представьте, что один или оба из 'x' и' y' являются '_ | _' и' compare' ленивы в соответствующем аргумент). –

+0

@ReidBarton Исходная версия также была строгой в обоих аргументах. –