Не могу доказать :-(
Dec. 6th, 2007 02:57 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Небольшое вступление.
Есть такой модуль Control.Applicative, в котором определён класс Applicative
т.е. он чуть шире
Так вот есть такой метод:
Однако его реализация в исходниках такая:
Я попытался привести это выражение к
В это месте у меня затык. Предположив, что
Ну и возвращая
ЧТД. Но! Я совершенно не уверен, что могу делать допущение подобное
Кто нибудь подскажет, как выровнять доказательство?
Есть такой модуль Control.Applicative, в котором определён класс Applicative
class Functor a => Applicative a where pure :: a -> f a <*> :: f (a -> b) -> f a -> f b
т.е. он чуть шире
Functor
(за счёт pure
), и чуть уже Monad
. Золотая середина - полезно, когда нам от монад нужен только return
.Так вот есть такой метод:
<**> :: f a -> f (a -> b) -> f b
, который по сути представляет собой перевёрнутый <*>
.Однако его реализация в исходниках такая:
(<**>) = liftA2 (flip ($))
Я попытался привести это выражение к
flip (*)
и вот что у меня получилось:liftA2 (flip ($)) \a b -> (flip ($)) <$> a <*> b -- definition of liftA2 \a b -> (fmap (flip ($)) a) <*> b -- definition of l<$> \a b -> (pure (flip ($)) <*> a) <*> b -- Functor instance rule: f `fmap` a = pure f <*> a
В это месте у меня затык. Предположив, что
a = pure a'
можно получить\a' b -> (pure (flip ($)) <*> pure a') <*> b -- a = pure a' \a' b -> pure (flip ($) a') <*> b -- homomorphism rule: pure f <*> pure x = pure (f x) \a' b -> pure ($ a') <*> b -- flip ($) x = ($ x) \a' b -> b <*> pure a' -- interchange rule: u <*> pure y = pure ($ y) <*> u
Ну и возвращая
a
на место вместо a'
\a b -> b <*> a flip (<*>)
ЧТД. Но! Я совершенно не уверен, что могу делать допущение подобное
a = pure a'
.Кто нибудь подскажет, как выровнять доказательство?
no subject
Date: 2007-12-06 01:18 pm (UTC)Таким образом ты просто конструируешь значение a :: Applicative f => f a. То есть, вкладываешь вычисление значения a' внутрь f, а это по другому сделать нельзя.
no subject
Date: 2007-12-06 01:19 pm (UTC)no subject
Date: 2007-12-06 01:50 pm (UTC)По этому тексту получается вот, что:
Скобки можно переставлять и раскрывать? По статье - можно.
\a b -> pure (flip ($)) <*> a <*> b
Тут дальше лог с выводом типов, не то, чтобы это было доказательством, но, может, на что натолкнет:
Первым параметром мы можем подставить f a, получим Applicative f => f ((a->b)->b). Если обединить (pure (flip ($)) <*> a) с (b :: f (a->b)) путем применения <*>, то и получим f b.
Как-то так.
Порядок применения эффектов в Applicative f сохраняется.
no subject
Date: 2007-12-06 02:35 pm (UTC)Раскрывать можно - ассоциация левая, а вот переставлять нельзя:
Есть composition rule:
Но мне не удалось свести к нему.
Насчёт вывода типов, я им активно пользовался в доказательстве, в посте я просто перевод с него сделал :-)
Насчёт доказательства:
1. Ни в одном из законов нет вывода аргумента из под pure, значит трюк с гомоморфизмом не применишь (всё равно вытаскивать придётся a и b)
2. Ни в одном из законов, кроме interchange нельзя обернуть параметры (флип), а interchange использует pure, из под которого уже не выведешь аргмент
Это меня убеждает в том, что с помощью законов и определений участвующих в уравнении функций, нельзя построить доказательство.
Т.е. можно построить доказательство, что
liftA2 (flip ($)) (pure a) (pure b) = pure b <*> pure a
Но вот с a и b никак - их с трубы не снимешь :-(
no subject
Date: 2007-12-06 03:28 pm (UTC)pure (выраженное через fmap, или так) производит некий "нулевой эффект," E0. Он устроен так, что E0 <*> E0 = E0, E <*> E0 = E и E0 <*> E = E0. Это можно вывести из законов, что в книжке, как я понимаю.
Как-то так: Вроде, последовательность эффектов соблюдена.
Кстати, <*> - это символ последовательного разбора в Utrecht University parsers library. А <$>, по-моему, там был в начале последовательного разбора.
Типа такого: Но это уже оффтопик. ;)
no subject
Date: 2007-12-07 09:43 am (UTC)Почему
E <*> E0 = E
а
E0 <*> E = E0?
Насчёт библиотеки парсеров интересно - может быть это экземпляр парсера для Control.Applicative?
Ну и напоследок: почитай ниже коммент
no subject
Date: 2007-12-07 11:16 am (UTC)E0 - правый и левый нуль-эффект. E0 <*> E = E и E <*> E0 = E. Но, как показал
Парсеры были раньше, они появились году в 2002-ом. ;)
no subject
Date: 2007-12-06 05:19 pm (UTC)С точки зрения бананов и линз тип
задаёт f-коалгебру (pure там - это psi в анаморфизме). Ну и для функторов есть изоморфизм между f a и a. Так что вроде можно, но я не настолько крут в бананах, чтобы поставить тут ЧТД :)
no subject
Date: 2007-12-07 09:29 am (UTC)no subject
Date: 2007-12-07 10:42 am (UTC)no subject
Date: 2007-12-07 10:54 am (UTC)no subject
Date: 2007-12-07 02:08 pm (UTC)no subject
Date: 2007-12-07 03:45 pm (UTC)no subject
Date: 2007-12-07 04:46 pm (UTC):)
no subject
Date: 2007-12-07 12:29 pm (UTC)no subject
Date: 2007-12-07 02:05 pm (UTC)offtop
Date: 2007-12-07 12:05 am (UTC)http://okmij.org/ftp/Haskell/types.html#restricted-datatypes
?
Re: offtop
Date: 2007-12-07 09:57 am (UTC)no subject
Date: 2007-12-07 09:12 am (UTC)no subject
Date: 2007-12-07 09:28 am (UTC)no subject
Date: 2007-12-07 09:30 am (UTC)"A variant of <*> with the arguments reversed."
Поверил, понимаешь, на слово!