Создание алгебраического типа данных в Haskell, который имеет либо Int, либо их массив - PullRequest
0 голосов
/ 03 июля 2019

Мне нужен тип данных, который либо содержит точное значение, либо содержит список возможных кандидатов. (Я буду использовать значения типа Int).

Я бы хотел, чтобы, если я выполняю функцию f: Int -> ... для Cell, которая имеет точное значение, она выполняется для значения, и если я выполняю функцию вида f : [Int] -> ... для Cell с кандидатами выполняет функцию над массивом кандидатов. Поэтому я определяю свои данные так:

data Cell a = Exactly a | Candidates [a] deriving (Eq, Read, Show)

instance Functor Cell where  
    fmap f (Exactly x) = Exactly (f x)  
    fmap f (Candidates (x:xs)) = Candidates ( f (x:xs)) 

Это не компилируется и выдает ошибку вида

Occurs check: cannot construct the infinite type: b ~ [b] ...

Если я отредактирую свой код на

fmap f (Candidates (x:xs)) = Candidates ( map f (x:xs))

это скомпилирует, но потом не выполняет мою функцию, так как иногда мне придется работать над всем массивом, а не по элементам.

Спасибо за помощь.

1 Ответ

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

Ваша проблема с этой строкой

fmap f (Candidates (x:xs)) = Candidates ( f (x:xs))

, функция f работает только для отдельных значений, и вы пытаетесь применить ее к списку.Вам нужно применить f к каждому элементу в списке.

Попробуйте:

fmap f (Candidates xs) = Candidates ( fmap f xs)

Это применимо к каждому члену xs.


Кроме того, читали ли вы эту статью (или аналогичную) о монаде списка?

...