Nano Hash - криптовалюты, майнинг, программирование

C-style enum в Haskell?

В C мы определяем enum следующим образом:

enum E {
    E0,
    E1,
    E2 = 3,
    E3
};

Обратите внимание на выражение E2 = 3, результат типа перечисления будет E0 == 0, E1 == 1, E2 == 3, E3 == 4.

В Haskell у нас нет возможности указать перечисление в объявлении. Единственный способ реализовать прерывистое перечисление - это реализовать класс Enum вручную.

Есть какой-нибудь удобный способ это сделать?

Я написал демонстрацию, используя Template Haskell для создания экземпляра Enum.

data E = E0
       | E1
       | E2_3
       | E3
       deriving Show

enum ''E

Интересно, есть ли библиотеки, пытающиеся восполнить этот пробел?

06.11.2015

  • Какую основную проблему вы хотите решить? 06.11.2015
  • @Franky, я пытаюсь разобрать двоичный файл, созданный программой, написанной на C. 06.11.2015
  • @wenlong: не могли бы вы использовать c2hs для генерации типа перечисления? 06.11.2015

Ответы:


1

Вы можете сделать что-нибудь маленькое и простое, используя reifyAnnotations функцию Template Haskell.

Во-первых, нам нужно определить тип аннотации для хранения значений перечисления:

{-# LANGUAGE DeriveDataTypeable #-}
module Def where

import Data.Data

data EnumValue = EnumValue Int deriving (Typeable, Data)

Во-вторых, нам понадобится немного кода TH, чтобы использовать эти аннотации и превратить их в Enum определения экземпляров:

{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
module TH where

import Def
import Language.Haskell.TH.Syntax
import Language.Haskell.TH
import Control.Monad
import Data.List (mapAccumL)
import Data.Maybe

enumValues :: [(a, Maybe Int)] -> [(a, Int)]
enumValues = snd . mapAccumL (\next (x, mv) -> let v = fromMaybe next mv in (v+1, (x, v))) 0

enumFromAnns :: Name -> Q [Dec]
enumFromAnns name = do
    TyConI (DataD _ _ _ cons _) <- reify name
    eVals <- fmap enumValues $ forM cons $ \(NormalC conName []) -> do
        anns <- reifyAnnotations (AnnLookupName conName)
        let ev = case anns of
                [EnumValue ev] -> Just ev
                [] -> Nothing
        return (conName, ev)
    [d|
     instance Enum $(conT name) where
       fromEnum = $(lamCaseE [match (conP c []) (normalB $ lift v) [] | (c, v) <- eVals])
       toEnum =  $(lamCaseE [match (litP . IntegerL . fromIntegral $ v) (normalB $ conE c) [] | (c, v) <- eVals])|]

И, наконец, мы можем использовать его (с помощью небольшого обходного пути, чтобы сделать убедитесь, что использование находится в новой группе объявлений):

{-# LANGUAGE TemplateHaskell #-}
module AnnotatedEnumExample where

import Def
import TH

data E = E1
       | E2
       | E42
       | E43
       deriving Show

{-# ANN E1 (EnumValue 1) #-}
{-# ANN E42 (EnumValue 42) #-}

-- Force new declaration group
return []

enumFromAnns ''E

Пример использования:

*AnnotatedEnumExample> map fromEnum [E1, E2, E42, E43]
[1,2,42,43]
*AnnotatedEnumExample> map toEnum [1, 2, 42, 43] :: [E]
[E1,E2,E42,E43]
06.11.2015
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..