Каковы прикладные законы функтора в терминах pure и liftA2?

я играю с формулировкой Applicative с точки зрения pure и liftA2 (Так что (<*>) = liftA2 id становится производным комбинатором).

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

  1. f <$> pure x = pure (f x)
  2. f <$> liftA2 g x y = liftA2 ((f .) . g) x y
  3. liftA2 f (pure x) y = f x <$> y
  4. liftA2 f x (pure y) = liftA2 (flip f) (pure y) x
  5. liftA2 f (g <$> x) (h <$> y) = liftA2 (x y -> f (g x) (h y)) x y
  6. ...

2 ответов


на основе Макбрайда и Патерсона законы Monoidal(раздел 7) я бы предложил следующие законы для liftA2 и pure.

левая и правая идентичность

liftA2 (\_ y -> y) (pure x) fy       = fy
liftA2 (\x _ -> x) fx       (pure y) = fx

ассоциативность

liftA2 id           (liftA2 (\x y z -> f x y z) fx fy) fz =
liftA2 (flip id) fx (liftA2 (\y z x -> f x y z)    fy  fz)

натуральность

liftA2 (\x y -> o (f x) (g y)) fx fy = liftA2 o (fmap f fx) (fmap g fy)

не сразу очевидно, что этого достаточно, чтобы охватить отношения между fmap и Applicative ' s pure и liftA2. Посмотрим, сможем ли мы доказать из вышеприведенных законов, что

fmap f fx = liftA2 id (pure f) fx

начнем с работы над fmap f fx. Все нижеследующее эквивалентно.

fmap f fx
liftA2 (\x _ -> x) (fmap f fx) (         pure y )     -- by right identity
liftA2 (\x _ -> x) (fmap f fx) (     id (pure y))     -- id x = x by definition
liftA2 (\x _ -> x) (fmap f fx) (fmap id (pure y))     -- fmap id = id (Functor law)
liftA2 (\x y -> (\x _ -> x) (f x) (id y)) fx (pure y) -- by naturality
liftA2 (\x _ -> f x                     ) fx (pure y) -- apply constant function

в этот момент мы написали fmap С точки зрения liftA2, pure и ни y; fmap полностью определяется вышеуказанными законами. Оставшаяся часть пока еще недоказанного доказательства оставлена нерешительным автором в качестве упражнения для читатель.


ТВ онлайн-книги узнайте вы Haskell: функторы, аппликативные функторы и моноиды, законы Appplicative функтора ниже, но реорганизованы по причинам форматирования; однако я делаю это сообщество редактируемым, так как было бы полезно, если бы кто-то мог вставлять деривации:

    identity]               v = pure id <*> v
homomorphism]      pure (f x) = pure f <*> pure x
 interchange]    u <*> pure y = pure ($ y) <*> u
 composition] u <*> (v <*> w) = pure (.) <*> u <*> v <*> w

Примечание:

function composition]  (.) = (a->b) -> (b->c) -> (a->c)
application operator]    $ = (a->b) -> a -> b

найдено лечение на Reddit