2014-05-13 3 views
1

Мне нужно экспортировать некоторые перечисления из кода C++. https://github.com/horde3d/Horde3D/blob/master/Horde3D/Bindings/C%2B%2B/Horde3D.hEnum с начальным значением

struct H3DGeoRes 
{ 
    enum List 
    { 
     GeometryElem = 200, 
     //... 
    }; 
}; 

struct H3DAnimRes 
{ 
    enum List 
    { 
     EntityElem = 300, 
     //... 
    }; 
}; 

Как я могу написать это в Haskell? Могу ли я переопределить fromEnum для типа?

data H3DGeoRes = GeometryElem | ... deriving (Show, Eq, Ord, Bounded, Enum) 
data H3DAnimRes = EntityElem | ... deriving (Show, Eq, Ord, Bounded, Enum) 

-- not work 

instance Enum H3DGeoRes where 
    fromEnum x = (fromEnum x) + 200 

instance Enum H3DAnimRes where 
    fromEnum x = (fromEnum x) + 300 
+0

Да, вы абсолютно правы. Проблема в том, что вам придется писать 'fromEnum' путем сопоставления шаблонов, то есть' fromEnum GeometryElem = 200'. Текущий код бесконечно рекурсивный. Вы можете управлять шаблоном с использованием расширения Template Haskell для генерации этих экземпляров. –

+0

Спасибо, http://codepad.org/JG6tFGWF это работает, но мне нужно много констант перечисления. Возможно, есть способы укоротить – Alexes

+0

Взгляните на этот код. Это совершенно понятно. Насколько я знаю, нет более простого способа сделать это. http://www.haskell.org/haskellwiki/Template_haskell/Instance_deriving_example –

ответ

1

Один из способов решить проблему, не слишком много печатать, чтобы создать новый класс типа, похожий на Enum. Давайте назовем это Enumerable:

class Enumerable a where fromEnumerable :: a -> Int

Вы можете написать экземпляр для Enumerable с помощью Enum:

instance Enumerable H3DGeoRes where fromEnumerable x = fromEnum x + 200

Всякий раз, используя перечисление ваших типов H3DGeoRes и H3DAnimRes вам придется использовать функции от класса Enumerable, а не класса Enum. Это немного неприятно, так как это помешает вам использовать удобный синтаксис списка для Enum.

+0

Большое спасибо! – Alexes

+0

Этот класс не имеет контекстного запроса как 'class (Enum a) => Enumerable a where ...', поскольку вы используете методы Enum. –

+0

@GabrielRiba, ограничение класса не требуется, если вы не должны использовать функции из «Enum» для определения функций по умолчанию в классе «Enumerable». Но, возможно, было бы естественно добавить ограничение в любом случае. – svenningsson

Смежные вопросы