Entry tags:
Кстати!
Для equational reasoning в Haskell можно (иногда нужно) пользоваться GHC Rules (На Haskellwiki), чтобы написанное было читабельным и maintainable, а скомпилированное эффективным. А для нахождения нужных правил можно воспользоваться Theorem for Free. Например, его автоматической выводилкой. Или использовать free / ft команды lambdabot-а.
К сожалению, что нибудь более-менее автоматического для типов, отличных от стандартных, я найти не могу. Остаётся или выводить правила руками, или строить по аналогии со стандартными, а затем проверять на корректность.
Это я всё мечтаю. Нарисовал нужные типы данных, сформировал по ним типы функций для работы над ними, автоматически построил их реализацию, автоматически построил правила, выбрал нужные для оптимизации. А дальше работаешь легко и непринуждённо. Это идеал, разумеется. Но я уверен, что частично эту работу можно автоматизировать. Типа того, что при доказательстве Coq'ом ему надо указывать стратегии, так же и здесь при реализации тела функции надо направлять "думатель".
Это вообще возможно? А то у меня каша в голове.
К сожалению, что нибудь более-менее автоматического для типов, отличных от стандартных, я найти не могу. Остаётся или выводить правила руками, или строить по аналогии со стандартными, а затем проверять на корректность.
Это я всё мечтаю. Нарисовал нужные типы данных, сформировал по ним типы функций для работы над ними, автоматически построил их реализацию, автоматически построил правила, выбрал нужные для оптимизации. А дальше работаешь легко и непринуждённо. Это идеал, разумеется. Но я уверен, что частично эту работу можно автоматизировать. Типа того, что при доказательстве Coq'ом ему надо указывать стратегии, так же и здесь при реализации тела функции надо направлять "думатель".
Это вообще возможно? А то у меня каша в голове.
no subject
no subject
no subject
В том проекте - модели МИПСа у нас как раз и была такая структура. Сперва сдедали тип, затем в целях улучшения скорости я сперва расставил {-# pragma INLINE #-}, а затем еще и правила подключил.
Особого эффекта, кстати, не дало.
no subject
Или достаточно хотя бы каких-то теорем для заданного нового типа + стандартный базис?
Для классических халявных теорем под стандартным базисом я имею ввиду map и его аналог для кортежей
-- У Вадлера это * у функции
map :: (a -> a') -> [a] -> [a']
map f [xs] = [f xs]
-- аналог map для кортежей
(***) :: (a -> a') -> (b -> b') -> (a, b) -> (a', b')
(***) f g (x, y) = (f x, g y)
no subject
Это что то вроде всяких помощников "создать геттеры/сеттеры", "добавить конструктор от суперкласса" в ОО. Какие то шаблонные действия. Плюс попытка помочь при выводе правил. Например, видишь, что в данной композици создаётся промежуточная структура. Попробовать найти способ для elimination исходя из композиции функций. Аналогично тому как мы сами размышляем, когда делаем эту операцию.
no subject
Ну правила сами по себе мне не нужны :) Они мне нужны для каких то моих строк кода. Т.е. пишу я "map f . map g", и тут можно автоматически определить, что посередине создаётся временный список. Делается попытка именно для этого случая подыскать (сгенерировать) правило, находится "map (f . g)", где этого списка нет.
Мне почему то кажется, что для таких условий (заранее известное выражение, заданная цель) можно провести переписывание с помощью равенств. Только я не разбираюсь во всех этих term rewriting и автоматических equational proving или как они там называются. Потому и спрашиваю вас, о мудрейшие из проницательнейших!
> Или достаточно хотя бы каких-то теорем для заданного нового типа + стандартный базис?
Для начала хотя бы это. Возможно?
no subject
Даже и сказать-то особо нечего. ;)
Когда я занимался написанием частичных дифференциалов почти в промышленных масштабах (в смысле - много и несколько раз переписывал), у меня возникала мысль о построении генератора упростителей на основе алгоритма Knuth-Bendix. Руки, правда, не дошли.
no subject
Ну и что почитать, конечно :-) С чего начать, чтобы в теме хоть чуть чуть ориентироваться.
no subject
Есть еще http://www.program-transformation.org/
Там не очень много, но есть от чего отталкиваться.
no subject
no subject
Ну я, ничтожнейший из глупейших, могу поделиться лишь своими убогими мыслишками, скорее всего неправильными. :)
Hugs> :t \f g -> fmap f . fmap g
\f g -> fmap f . fmap g :: Functor a => (b -> c) -> (d -> b) -> a d -> a c
Hugs> :t \f g -> fmap (f . g)
\f g -> fmap (f . g) :: Functor a => (b -> c) -> (d -> b) -> a d -> a c
То что ты пишешь про map - шире, чем просто игры со списками. Это для любого функтора верно и является для него одной из двух аксиом
fmap id == id
fmap (f . g) == fmap f . fmap g
Поэтому про тип, параметризованные другим типом правильный вопрос такой - является ли он функтором? Всякий ли однопараметрический алгебраический тип - функтор?
data X a = ... -- тут любая допустимая хрень
Вот я кажется сформулировал вопрос в который сам всегда утыкаюсь - какие свойства есть у X независимо от того что написано справа?
ЗЫ: это вышел просто поток сознания, а не ответ на твой вопрос :)
no subject
> Всякий ли однопараметрический алгебраический тип - функтор?
В случае negative type (или как они там называются, когда переменная слева от стрелки) вроде не работает:
data X a = X (a -> Int)
Тут не к чему (a -> b) применить, чтобы получить X b.
> какие свойства есть у X независимо от того что написано справа?
Он обладает kind :: * -> *. Это уже что-то для анализа, например, при создании экземпляра класса.
З.Ы. А почему Hugs?
no subject
> З.Ы. А почему Hugs?
За таким компьютером оказался, где только он и есть :)
почитав Вадлера и про ТК на отдыхе в деревне :)
>Для начала хотя бы это. Возможно?
Вроде да.
Собственно халявные теоремы действительно халявные, как я теперь понял :)
Есть у тебя, скажем, функция с типом f :: forall a. a -> a -> C a -> [a]
Пишешь её два раза
f :: a1 -> C a1 -> [a1]
f :: a2 -> C a2 -> [a2]
Поскольку a живёт под квантором общности, то код f каким бы он ни был, не может зависеть ни от каких свойств типа a. А это даёт магическую parametricity: для любой g:a1 -> a2 (то есть вообще для любой функции!) квадрат коммутативен:
То есть пофиг, что делать: сначала применить f, а потом g на кодомене f, или сначала g над всеми вхождениями a1 в домене f, а потом f над её отображённым в a2 доменом.
Осталось протащить g через параметризованные типы в домене и кодомене и халявная теорема готова:
map g (f x xs) = f (g x) (fmap g xs)
Слева от равенства: верхняя (f x xs), а затем правая (map g) стрелки, map - ибо g в кодомене вытаскиваем из списка.
Справа от равенства: сначала протаскиваем g через параметры (предположим, что C - функтор), а потм применяем f над типом a2.
Если же для C нет instance Functor, то надо как-то курить его конструкторы, это, похоже, должно породить дополнительные условия в халявной теореме.
PS. Я много чего в деревне подоказывал, например, что единственная функция с типом композиции - это композиция :)
Re: почитав Вадлера и про ТК на отдыхе в деревне :)
Re: почитав Вадлера и про ТК на отдыхе в деревне :)
>Чувствую, в деревне с ТК хорошо :)
В деревне с ТК отлично! ;)
Жалел, что мало статей взял. Зато без компьютера, с ручкой и бумагой, знания в голове оседают гораздо лучше. Я, видимо, ретроград :)
>В пятницу-субботу тоже поеду на пару недель ;-)
А я завтра в Абхазию. ;-)
Re: почитав Вадлера и про ТК на отдыхе в деревне :)
Re: почитав Вадлера и про ТК на отдыхе в деревне :)
Мне, наверное, тоже. Но парочку распечатать стоит. Про запас ;)
Сейчас вот думаю, какие.