Поля типа данных Haskell

#haskell #types

#haskell #типы

Вопрос:

У меня есть свой собственный тип данных:

 type Types = String
data MyType = MyType [Types]
  

У меня есть служебная функция:

 initMyType :: [Types] -> MyType
initMyType types = Mytype types
  

Теперь я создаю:

 let a = MyType ["1A", "1B", "1C"]
  

Как я могу получить список ["1A", "1B", "1C"] из a ? И вообще, как я могу получить данные из конструктора данных?

Ответ №1:

Помимо использования сопоставления с образцом, как в ответе arrowdodger, вы также можете использовать синтаксис записи для автоматического определения средства доступа:

 data MyType = MyType { getList :: [Types] }
  

Это определяет тип, точно такой же, как

 data MyType = MyType [Types]
  

но также определяет функцию

 getList :: MyType -> [Types]
  

и допускает (но не требует) синтаксис MyType { getList = ["a", "b", "c"] } для построения значений MyType. Кстати, initMyTypes на самом деле это не обязательно, если только оно не выполняет что-то еще, кроме построения значения, потому что оно выполняет точно то же самое, что и конструктор MyType (но не может использоваться при сопоставлении с шаблоном).

Ответ №2:

Вы можете сопоставить их с шаблоном где-нибудь в своем коде или написать функцию деконструкции:

 getList (MyType lst) = lst
  

Ответ №3:

В Haskell существует множество способов сопоставления с шаблоном. Смотрите http://www.haskell.org/tutorial/patterns.html для получения подробной информации о том, где могут использоваться шаблоны (например, операторы case), а также о различных типах шаблонов (отложенные шаблоны, шаблоны ‘as’ и т.д.)

Ответ №4:

(Ответ для будущих поколений.)

Итак, ваша задача — получить все поля из конструктора типа данных.
Вот довольно элегантный способ сделать это.

Мы собираемся использовать DeriveFoldable расширение GHC, поэтому, чтобы включить его, мы должны изменить ваше объявление типа данных следующим образом: data MyType a = MyType [a] deriving (Show, Foldable) .

Вот общий способ получения всех данных из конструктора данных.
Это полное решение:

 {-# LANGUAGE DeriveFoldable #-}

import Data.Foldable (toList)

type Types = String
data MyType a = MyType [a] deriving (Show, Foldable)

main = 
  let a      = MyType ["1A", "1B", "1C"] :: MyType Types
      result = toList a
  in print result
  

При печати результата вы получите ‘[«1A», «1B», «1C»]’, как вы и хотели.