Haskell: Понимание пользовательских типов данных - PullRequest
3 голосов
/ 07 июля 2019

Я пытаюсь создать свой собственный тип данных в Haskell.

У меня есть следующие типы данных:

type Length = Integer 
type Rotation = Integer 
data Colour = Colour { red, green, blue, alpha :: Int }
            deriving (Show, Eq)

Я пытаюсь создать собственный тип данных, который может бытьлюбой из указанных выше типов данных.У меня есть следующее:

data Special 
  = L Length 
  | R Rotation 
  | Col Colour  
  deriving (Show, Eq) 

Однако я хотел бы иметь возможность извлечь значения Length, Rotation и Colour, если у меня есть экземпляр типа данных Special.

Если бы у меня было:

L length

Был бы length здесь типа Special или типа Length?Если length имеет тип Special, есть ли способ извлечь его, чтобы он имел тип Length?

Например, допустим ли следующий код?

takeL (x:xs)
      | x == (L length) = length

Любойпонимание приветствуется.

Ответы [ 2 ]

4 голосов
/ 07 июля 2019

Чтобы выражение L length было допустимым, length должно быть Length (потому что L :: Length -> Special).

takeL (x:xs)
      | x == (L length) = length

недопустимо.Если вы не переопределите где-то length, length - это функция [a] -> Int из стандартной библиотеки, поэтому L length - это ошибка типа.

Я думаю, что вы пытаетесь сделать здесьпросто сопоставление с образцом:

takeL (L length : xs) = length
3 голосов
/ 07 июля 2019

Определение типа данных

data Special  = 

читает: Special - это новый тип , такой, что для создания значения типа Special,

                  L Length 
  • call L l, где l - значение типа Length; или

                | R Rotation 
    
  • вызов R r, где r - значение типа Rotation; или

                | Col Colour  
    
  • вызов Col c, где c - значение типа Colour.


Чтобы проанализировать значение типа Special, необходимо рассмотреть три случая:

foo :: Special -> ...
foo val = 
    case val of
        L   l -> ...  
  • l - это значение типа Length, в случае val было фактически L l; или

        R   r -> ... 
    
  • r - это значение типа Rotation, в случае val было фактически R r; или

        Col c -> ...  
    
  • c - это значение типа Colour, в случае val на самом деле Col c.

Синтаксис case в определениях функций также может быть выражен с помощью предложений на основе шаблона:

foo :: Special -> ...
foo (L   l) = ...
foo (R   r) = ...
foo (Col c) = ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...