Если ColumnA
считается некоторой ошибкой, вы не можете позволить ей обернуть значение a
. Верно. Идея (<*>)
состоит в том, что он принимает Choice (x -> y)
и Choice x
и возвращает Choice y
. Но если у вас есть ColumnA
, заключающий в себе функцию типа x -> y
, и у вас справа Choice x
, то он, таким образом, должен вернуть Choice y
, а не Choice x
.
То, что вы можете сделать, это определить тип с двумя параметрами типа, например:
data Choice <b>a b</b> = ColumnA <b>a</b> | ColumnB <b>b</b>
, тогда вы будете выполнять сопоставление только с конструктором данных ColumnB b
:
instance Functor (Choice <b>a</b>) where
fmap _ (ColumnA e) = ColumnA e
fmap f (ColumnB x) = ColumnB (f x)
и тогда мы можем определить экземпляр Applicative
как:
instance Applicative (Choice <b>a</b>) where
pure = ColumnB
ColumnB f <*> ColumnB x = ColumnB <b>(f x)</b>
ColumnA e <*> _ = ColumnA e
_ <*> ColumnA e = ColumnA e
Такой экземпляр для Functor
и Applicative
, однако, уже существует: так он определен в Either
тип данных .