Представимый функтор, изоморфный (Bool -> a)

Я подумал, что попробую интригующие Представимые функторы Пакет для определения Монады и 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

Итак, правильно ли и идиоматически я выполнил требования класса Представляемый ?

15
задан Community 23 May 2017 в 10:29
поделиться