Каков рекомендуемый способ обработки сложно составленного модуля (plain-old-data в OO) в Haskell?

StackOverflow https://stackoverflow.com/questions/4976139

  •  12-11-2019
  •  | 
  •  

Вопрос

Я новичок в Haskell.

В статически типизированных OO-языках (например, Java) все сложные структуры данных представлены в виде классов и экземпляров.Объект может иметь множество атрибутов (полей).И другим объектом может быть значение поля.К этим полям можно получить доступ по их именам и статически ввести по классу.Наконец, эти объекты строят огромный граф объектов, которые связаны друг с другом.Большинство программ использует график данных, подобный этому.

Как я могу заархивировать эти функции в Haskell?

Это было полезно?

Решение

HASKELL имеет алгебраические типы данных, которые могут описать структуры или союзы структур, так что что-то данного типа может иметь одно из нескольких различных наборов полей.Эти поля могут быть установлены и доступны как к позиционному или по именам с помощью синтаксиса записи.

См. Здесь: http://learnyouahaskell.com/makey-тип-и-типографы

Другие советы

Если у вас действительно есть данные без поведения, это прекрасно соотносится с записью на Haskell:

data Person = Person { name    :: String
                     , address :: String }
            deriving (Eq, Read, Show)

data Department = Management | Accounting | IT | Programming
                deriving (Eq, Read, Show)

data Employee = Employee   { identity   :: Person
                           , idNumber   :: Int
                           , department :: Department }
              | Contractor { identity :: Person
                           , company  :: String }
              deriving (Eq, Read, Show)

Это говорит о том, что Person это Person у кого есть name и address (оба Stringы);a Department является либо Management, Accounting, IT, или Programming;и ан Employee является либо Employee у кого есть identityPerson), ан idNumber (ан Int), и a departmentDepartment), или является Contractor у кого есть identityPerson) и a companyString).То deriving (Eq, Read, Show) строки позволяют вам сравнивать эти объекты на предмет равенства, считывать их и преобразовывать в строки.

В общем, тип данных Haskell представляет собой комбинацию объединений (также называемых суммы) и кортежи (также называемые продукты).1 То |s обозначает выбор (союз):один Employee является любой один Employee или в Contractor, а Department это одна из четырех вещей и т.д.В общем случае кортежи записываются примерно следующим образом:

data Process = Process String Int

Это говорит о том, что Process (в дополнение к имени типа) - это конструктор данных в день тип настройки? String -> Int -> Process.Таким образом, например, Process "init" 1, или Process "ls" 57300.A Process должен иметь оба a String и ан Int существовать.Обозначение записи, используемое выше, является просто синтаксическим сахаром для этих продуктов;Я также мог бы написать data Person = Person String String, а затем определяется

name :: Person -> String
name (Person n _) = n

address :: Person -> String
address (Person _ a) = a

Однако нотация записей может быть полезна для сложных структур данных.

Также обратите внимание, что вы можете параметризовать тип Haskell по сравнению с другими типами;например, трехмерной точкой может быть data Point3 a = Point3 a a a.Это означает, что Point3 :: a -> a -> a -> Point3 a, чтобы можно было написать Point3 (3 :: Int) (4 :: Int) (5 :: Int) чтобы получить Point3 Int, или Point3 (1.1 :: Double) (2.2 :: Double) (3.3 :: Double) чтобы получить Point3 Double.(или Point3 1 2 3 чтобы получить Num a => Point3 a, если вы видели классы типов и перегруженные числовые литералы.)

Это то, что вам нужно для представления графика данных.Однако примите к сведению:одна из проблем для людей, переходящих с императивных языков на функциональные — или, на самом деле, между любыми двумя разными парадигмами (C на Python, Prolog на Ruby, Erlang на Java, что угодно) — заключается в том, чтобы продолжать пытаться решать проблемы старым способом.Решение, которое вы пытаетесь смоделировать мочь не может быть сконструирован способом, поддающимся простым методам функционального программирования, даже если проблема заключается в этом.Например, в Haskell очень важно думать о типах, в отличие, скажем, от Java.В то же время реализация поведения для этих типов выполняется совершенно по-разному:функции более высокого порядка захватывают некоторые абстракции, которые вы видели в Java, но также и некоторые, которые нелегко выразить(map :: (a -> b) -> [a] -> [b], filter :: (a -> Bool) -> [a] -> [a], и foldr :: (a -> b -> b) -> b -> [a] -> b приходит на ум).Так что оставляйте свои варианты открытыми и подумайте о том, чтобы решать свои проблемы функциональным способом.Конечно, может быть, в этом случае вы и действуете на полную катушку.Но имейте это в виду, когда будете изучать новый язык.И получайте удовольствие :-)


1: И рекурсия:вы можете представить бинарное дерево, например, с помощью data Tree a = Leaf a | Branch a (Tree a) (Tree a).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top