Несколько instance для одного типа.

21 views
Skip to first unread message

Paul Graphov

unread,
Jul 5, 2011, 4:41:06 AM7/5/11
to spb...@googlegroups.com
Добрый день. После некоторого перерыва решил освежить знания и сделать небольшую программу на хаскеле.

Столкнулся со следующей проблемой:

Есть структура данных с несколькими полями, например:

data X = X {
  a :: Field,
  b :: Field,
  c :: Field
} deriving (Show)

Периодически нужно сортировать кучу этих структур по разным полям. Для этого подходит Data.MultiSet
Он, как и Data.Set, опирается на инстанс Ord для упорядочивания. Таким образом для каждого вида сортировки приходится делать newtype и instance Eq и Ord. При большом числе полей это становится уродливой копипастой.

Решил сделать type class WrappedX, который позволяет получить обратно X, а также получить Data.Accessor (функцию доступа к полю), по которому идет сортировка.
А потом объявить, что любой инстанс WrappedX также является инстансом Eq и Ord


(там используется Data.Accessor.Template для генерации accessor'ов - чего-то типа геттеров и сеттеров структуры)

FlexibleInstances, UndecidableInstances добавил по совету GHC.

В результате он говорит:
Overlapping instances for Ord Field
      arising from a use of `<=' at Main.hs:26:11-64
    Matching instances:
      instance (Ord a) => Ord [a] -- Defined in GHC.Base
      instance (WrappedX a) => Ord a -- Defined at Main.hs:25:9-27
.......

То есть, объявления а ля 
instance WrappedX a => Eq a where
он хочет применить ко всем типам, а не только тем, которые являются инстансами WrappedX. Это логично - я же могу в другом файле сделать инстанс WrappedX для Field.

Кук тут быть, как уменьшить бойлерплейт, реализовав Eq и Ord единожды на основании accessor'a?

Спасибо.

Paul Graphov

unread,
Jul 5, 2011, 4:42:59 AM7/5/11
to spb...@googlegroups.com
p.s. Если бы решал эту задачу на С++, взял бы boost multiindex container. Нет ли чего-нибудь похожено в хаскеле?

Daniil Elovkov

unread,
Jul 5, 2011, 6:54:41 AM7/5/11
to spb...@googlegroups.com, Paul Graphov
On 7/5/2011 12:41 PM, Paul Graphov wrote:
>
> http://hpaste.org/48742
>
> (О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ Data.Accessor.Template О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ accessor'О©╫О©╫ -
> О©╫О©╫О©╫О©╫-О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫)
>
> FlexibleInstances, UndecidableInstances О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ GHC.
>
> О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫:

> Overlapping instances for Ord Field
> arising from a use of `<=' at Main.hs:26:11-64
> Matching instances:
> instance (Ord a) => Ord [a] -- Defined in GHC.Base
> instance (WrappedX a) => Ord a -- Defined at Main.hs:25:9-27
> .......
>


О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫, О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ OverlappingInstances О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫?

О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫ cabal О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫ О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫,
О©╫О©╫О©╫ О©╫О©╫О©╫ О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫ data-accessor-template :)

О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫ О©╫О©╫О©╫, О©╫О©╫О©╫О©╫О©╫О©╫О©╫ О©╫О©╫ hpaste, О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫ О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫О©╫
О©╫О©╫О©╫О©╫О©╫О©╫?


--
Daniil Elovkov

Paul Graphov

unread,
Jul 5, 2011, 7:15:31 AM7/5/11
to spb...@googlegroups.com, Paul Graphov
Привет.
Что-то у меня твое вообщение полнейшим боржоми отображается.

Если что, вставляю из гмейла:
Привет Паша
Только тупое предположение, а разрешить OverlappingInstances не пробовал?
Запустить код не смог, опять cabal с версиями всего и вся поссорился, так что не установить data-accessor-template :)
Ошибку выдает именно этот код, который на hpaste, или более развернутая версия?

Да, что-то я протупил. Оно действительно помогает, мне почему-то подумалось, что это некрасиво. Хотя вроде ничего страшного, тем более, что это за пределы модуля видно не будет.

Спасибо.
Reply all
Reply to author
Forward
0 new messages