2015-03-12 4 views
9

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

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

  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. ...
+0

'liftA2' определяется в терминах' <$> 'и' <*> ', я не знаю, почему вы хотите вместо этого определить' <*> 'в терминах' liftA2'. – bheklilr

+0

Да, но я хотел бы сделать что-то похожее на то, что делает EZ Yang в своем посте, сравнивая аппликативные и моноидальные: http://blog.ezyang.com/2012/08/applicative-functors/ –

+2

'Applicative' с' pure 'и' liftA2' совпадает с классом ['Monoidal'] (http://www.haskellforall.com/2014/07/equational-reasoning-at-scale.html), который имеет список законов. Чтобы перейти от «Monoidal» к «Applicative» с 'pure' и' liftA2', вы замените явные типы и конструкторы в интерфейсе на то, что тип или конструктор может быть передан для восстановления исходного интерфейса] (http: // stackoverflow.com/a/27262462/414413). – Cirdec

ответ

7

основе (раздел 7) laws for Monoidal Макбрайд и Патерсона я бы SuG gest следующие законы для 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 «с 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 полностью определяется вышеуказанными законами. Остальная часть еще не доказанного доказательства остается нерешительным автором как упражнение для определенного читателя.

+0

Интересно, что закон тождественности можно переписать так: 'liftA2 const fx (pure y) == const fx (pure y)' и 'flip (liftA2 (flip const)) fx (pure y) == const fx (чистый y) '(или' liftA2 (flip const) (чистый x) fy == flip const (чистый x) fy'), что, возможно, добавляет интересный угол. –

0

В соответствии с онлайн-книгой Learn You A Haskell:Functors, Applicative Functors and Monoids законы Применительного Functor ниже, но реорганизованы для форматирования; однако, я делаю это сообщение сообщества редактируемым, так как это было бы полезно, если бы кто-то мог вставлять выкладок:

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 

Found a treatment on Reddit

+1

Должен '(.)' Не быть '(a-> b) -> (b-> c) -> (a-> c)'? – Zaaier

 Смежные вопросы

  • Нет связанных вопросов^_^