Сопоставление шаблонов для пользовательского конструктора данных, аналогичного спискам

#haskell #pattern-matching

Вопрос:

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

 data Stack a = Empty | NonEmpty a (Stack a)
         deriving (Show, Read, Eq)
 

Затем у меня есть функция, которая использует ее для сопоставления с образцом:

 func :: Stack a -> a
func (Stack.NonEmpty val Stack.Empty) = ...
func (Stack.NonEmpty val1 (Stack.NonEmpty val2 Stack.Empty)) = ...
 

То, что я хотел бы сделать, — это сопоставить шаблон аналогично тому, как последовательность или список делают это с помощью оператора, подобного этому:

 func :: Stack a -> a
func (val :> Stack.Empty) = ...
func (val1 :> val2 :> Stack.Empty) = ...
 

Я знаю, что на самом деле это не оператор, а конструктор данных, который выглядит как оператор, но я не смог заставить его работать.

Кроме того, я начал изучать Хаскелл несколько недель назад.

Ответ №1:

Вы можете определить :> как конструктор данных вместо NonEmpty :

 data Stack a = Empty | a :> Stack a
    deriving (Show, Read, Eq) 

тогда единственное, что вам все еще нужно сделать, это указать это как правоассоциативный оператор, который x :> y :> z анализируется как x :> (y :> z) :

 data Stack a = Empty | a :> Stack a
    deriving (Show, Read, Eq)

infixr 7 :> 

Вот 7 фиксированность и определите, что имеет приоритет, если есть два оператора.

Комментарии:

1. Большое спасибо.