Я подумал, что попробую интригующие Представимые функторы Пакет для определения Монады
и Comonad
экземпляра для функтора, заданного парой данных a = Pair aa
, которая может быть представлена Bool
]; как упоминалось в ответе на мой предыдущий вопрос о векторной монаде .
Первое, что я заметил, это то, что для того, чтобы сделать мой тип экземпляром Представляемого
, я должен не только определить табулируйте
и индекс
, но также убедитесь, что мой тип является экземпляром Indexable
, Distributive
, Keyed
, Применить классы типов
, Applicative
и Functor
. Хорошо, хорошо, index
завершает определение Indexable
, а функция <.>
из Apply
может использовать
из Applicative
; и это не должно ' Неудивительно, что требуется экземпляр Functor
. Тем не менее, я сомневаюсь, что мои экземпляры для Keyed
и Distributive
.
data Pair a = Pair a a
deriving (Show,Eq)
instance Functor Pair where
fmap f (Pair x y) = Pair (f x) (f y)
type instance Key Pair = Bool
instance Keyed Pair where
mapWithKey f (Pair x y) = Pair (f False x) (f False y)
instance Indexable Pair where
index (Pair x _) False = x
index (Pair _ y) True = y
instance Applicative Pair where
pure a = Pair a a
Pair f g <*> Pair x y = Pair (f x) (g y)
instance Apply Pair where
(<.>) = (<*>)
instance Distributive Pair where
collect f x = Pair (getL . f <$> x) (getR . f <$> x)
where getL (Pair x _) = x
getR (Pair _ y) = y
instance Representable Pair where
tabulate f = Pair (f False) (f True)
Мое определение mapWithKey
заимствовано из определения []
для Ключ
: хотя я не понимаю, почему 0
использовалось там для каждой итерации. Я аналогичным образом использовал False
для каждого члена пары
.
В заключение я определил экземпляры Monad
и Comonad
, I обнаружил, что Bool
требует определения полугруппы
для Extend
и определения моноида
для Comonad
. Я следую за экземпляром Semigroup
для Either
, который изоморфен (||)
, и выбираю False
для mempty
:
instance Monad Pair where
return = pureRep
(>>=) = bindRep
instance Monoid Bool where
mempty = False
mappend = (||)
instance Semigroup Bool where
(<>) = mappend
instance Extend Pair where
extend = extendRep -- needs Bool Semigroup
instance Comonad Pair where
extract = extractRep -- needs Bool Monoid
Итак, правильно ли и идиоматически я выполнил требования класса Представляемый
?