deniok: (Рыжий)
Как вам скорее всего известно, написать представителя класса типов Functor для типа эндоморфизма невозможно. Если неизвестно, то можете попробовать
newtype Endo a = Endo (a -> a)

instance Functor Endo where
   fmap f (Endo g) = Endo undefined
Даже если ваш результат сойдется по типам, законам для функтора он удовлетворять не будет.

Вот вам другой экспоненциальный тип данных, для которого, однако, написать законного представителя класса типов Functor можно:
newtype Quest b a = Quest ((a -> b) -> a)

instance Functor (Quest b) where
  fmap f (Quest g) = Quest undefined
Попробуйте сделать это, после чего ответьте на вопрос: чему равен результат такого вызова
> let Quest f = fmap succ $ Quest (\h -> h 40) in f id
deniok: (пацифик)
Объясните, почему невозможно по представителю Foldable для конструктора типа сгенерировать представителя Traversable.
deniok: (Рыжий)
Очень заманчивая идея о том, как в Agda загнать под капот навязчивые subst и cong. Пример от автора.

Про seq

Oct. 1st, 2015 12:29 am
deniok: (typed lambda)
Как известно seq вычисляет свой первый аргумент до слабой заголовочной нормальной формы (WHNF). Не пользуясь GHCi, ответьте на вопрос, каково будет значение следующего выражения
Prelude> (\True y -> ()) False `seq` 5
Проверьте себя в GHCi. Какова будет полученная в первом аргументе seq WHNF?

UPD. А теперь вопрос на засыпку: каково будет значение следующего выражения
Prelude> (\True -> \y -> ()) False `seq` 5
Считаете ли вы это правильным?
deniok: (пацифик)
А вот подскажите, на Haskell Wiki вот тут в последнем абзаце дурь написана, да? Никакой разницы между встроенными и пользовательскими частично примененными функциями нет?
Prelude> (+) undefined `seq` 5
5
Prelude> const undefined `seq` 5
5
Prelude> (\x y -> x) undefined `seq` 5
5
Или это только в последней версии GHC?

UPD. Нет, понял, там все верно, сам дурак. Пусть висит, демонстрирует мою глупость urbi et orbi.
deniok: (Рыжий)
Originally posted by [livejournal.com profile] scholar_vit at Как писать рекомендательные письма
Рекомендательные письма нужно писать коротко и по делу. Вот так, например:
ExpandRead more... )
deniok: (Рыжий)

Через неделю запускаем на stepic.org вводный онлайн-курс по Хаскелю Функциональное программирование на языке Haskell.

Когда начинал записывать лекции, обнаружил, что говорить без аудитории - отдельный скилл, так что первую треть курса произношу довольно скованно. Потом ничего, разошелся, руками стал размахивать. Еще, конечно, угнетало, что надо стоять на месте, обычно я бегаю вдоль доски туда-сюда.

В день, когда я закончил записываться, вышла новая версия Haskell Platform. C реализованными Functor-Applicative-Monad proposal и Foldable/Traversable in Prelude proposal. Очень своевременно. Типы кучи функций над списками в Prelude поменялись на более общие, Applicative я вообще не рассказывал, иначе в формат не уложиться было. Включил рекомендацию ставить прошлую версию Haskell Platform, либо пользоваться последней на свой страх и риск.

Организационно в CS Center все как всегда замечательно. Отдельное спасибо Кристине и Леше! Во всех вузах надо разогнать весь административно-бюрократический аппарат к чертям собачьим, на учебном и научно-исследовательском процессах это скажется немедленно и самым благотворным образом.

deniok: (удивлён)
Готовясь к завтрашней лекции про линзы, нашел в недрах Control.Lens.Traversal функцию с прекрасным именем confusing:
confusing :: Applicative f => LensLike (Rift (Yoneda f) (Yoneda f)) s t a b -> LensLike f s t a b
Пишут, что для fusion'а многих fmap в один.
deniok: (Рыжий)
Размышляю тут вторые сутки над вопросом, что делает контекст Foldable в определении класса типов Traversable
class (Functor t, Foldable t) => Traversable t where
  ...
Технически он не нужен: никакая функциональность Foldable не используется ни при выражении законов Traversable, ни для реализации по умолчанию его методов.

Контекст Functor, кстати, не вызывает вопросов в техническом отношении: он нужен и для формулировки законов (Naturality и Composition для sequenceA и Composition для traverse) и для реализации по умолчанию
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f

Соображения, которыми руководствовались разработчики класса типов Traversable, включая контекст Foldable, заключаются в довольно разумном соображении: любой Traversable является Foldable в том смысле, что имея traverse можно гарантированно и универсально реализовать Foldable с помощью нехитрой машинерии:
foldMap :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldMap f = getConst . traverse (Const . f)
(эта функция присутствует в Data.Traversable под именем foldMapDefault).

Тем не менее решение о "наследовании" Traversable от Foldable имеет свою цену. Теперь, объявляя некоторый тип MyType представителем Traversable, я должен сначала сделать его представителем Foldable. Даже если я совсем не собираюсь пользоваться Foldable-интерфейсом, я должен написать затычку
instance Foldable MyType where
    foldMap = foldMapDefault
Это не очень большая цена, но представим, что через пару лет ресерчеры обнаружат, что есть замечательный класс типов SomethingInterestingAndTrendyable и что с помощью traverse можно реализовать его единственную ключевую функцию somethingInterestingAndTrendyImpl. То есть Traversable является (is a :)
SomethingInterestingAndTrendyable и поэтому нужно сделать
class (Functor t, Foldable t, SomethingInterestingAndTrendyable t) => Traversable t where
  ...
а для "удобства" добавить somethingInterestingAndTrendyImplDefault. Не думаю, что мы будем этим очень довольны, хотя технически в каждый наш инстанс Traversable потребуется добавить лишь
instance SomethingInterestingAndTrendyable MyType where
    somethingInterestingAndTrendyImpl = somethingInterestingAndTrendyImplDefault


Но раз уж мы двинулись по этому пути "проявленных наследований" (а мы таки двинулись, см. Monad и Applicative), почему бы не переложить эту деятельность на компилятор? Вроде есть напрашивающееся решение: разрешить в Хаскелле в классах-наследниках задавать методы по умолчанию для классов-родителей. То есть вместо внешней по отношению к классу foldMapDefault и ей подобных разрешить писать
class (Functor t, Foldable t, SomethingInterestingAndTrendyable t) => Traversable t where
    -- default impls for Traversable methods
    traverse = ...
    -- default impls for parents methods
    fmap f = getId . traverse (Id . f)
    foldMap f = getConst . traverse (Const . f)
    somethingInterestingAndTrendyImpl = ...
В этом случае словари для родительских классов могут при необходимости генерироваться автоматически (если у нас достаточно реализаций по умолчанию), и разработчики будут освобождены от написания фейковых родительских инстансов.

Discuss.

UPD. В комментах сказали, что proposal такой имеется. Нашел, https://wiki.haskell.org/Class_system_extension_proposal, почитал. Мрак. C++ как мы его знаем, практически все прелести разрешения коллизий при множественном наследовании реализации. Нам такого не надо. Вывод: наследование - зло, его надо избегать, долой контекст Foldable из Traversable (и, как мне тут подсказывают, Applicative из Monad).
deniok: (Рыжий)
GHC 7.10.1 :
class Applicative m => Monad m where
...
    return      :: a -> m a
    return      = pure
...
-- оставили как было (по социальным причинам :)
--  (>>) :: forall a b. m a -> m b -> m b
--  (>>) = (*>)
...
https://hackage.haskell.org/package/base-4.8.0.0/candidate/docs/src/GHC-Base.html#Monad
deniok: (typed lambda)
Циклическую ротацию списка влево
> rotate 3 [1..10]
[4,5,6,7,8,9,10,1,2,3]
легко определить, используя take и drop:
> let rotate n xs = drop n xs ++ take n xs
Если напустить на это дело pointfree, он даст безумное:
rotate = ap (ap . ((++) .) . drop) take


Можете ли вы написать полностью бесточечную реализацию rotate, сцепив take и drop ровно одной стандартной библиотечной функцией?
deniok: (Рыжий)
Я осознал, как правильно перевести конфлюэнтность на русский язык. Конфлюэнтность это соборность.

TWIMC

Feb. 10th, 2015 10:05 pm
deniok: (ухмыляюсь)
Plan Foldable или Plan List?
deniok: (пацифик)
Originally posted by [livejournal.com profile] jeytim at Война: пособие для начинающих
Хорошую вещь альтруизм придумали не мы. Даже не мы придумали связать его с плохой вещью войной. Но именно мы довели эту связку любви к своим и ненависти к чужим до абсолюта. А дойдя до любого абсолюта, следует или просветлиться, или, пожав плечами, идти назад. В нашем случае, в пещеры.



Наш первый выпуск, заканчивающийся выносом мозга, мы сняли в Москве на кафедре антропологии МГУ, в атмосфере фильма “Весна”, среди разновозрастных скелетов и консервированных мозгов. В нем краткие, очень краткие, как мы умеем, итоги прошедшей истории человечества - и небольшая памятка на будущую.
Спасибо Александру [livejournal.com profile] macroevolution Маркову за то, что был нам музой и рецензентом, Станиславу Дробышевскому за мозги и гостеприимство, Сэмюэлю Боулсу за гипотезу коэволюции войн и парохиального альтруизма, Льву Толстому за то, что твердил нам об этом еще сто лет назад и [livejournal.com profile] akuaku за комикс.

deniok: (пацифик)
Мы привыкли, что правая свертка (foldr) хорошо заточена для работы с бесконечными списками:
> let mapPlusPi = foldr (\x xs -> (x+pi):xs) []
> head $ mapPlusPi [1..]
4.141592653589793
К сожалению, иногда возникают неприятности. Вот функция, которая берет список и выкидывает из него элементы стоящие на нечетных местах:
> let evenOnly = snd . foldr (\x (os,es) -> (x:es,os)) ([],[])
> evenOnly [1..10]
[2,4,6,8,10]
Только вот на бесконечном списке она ведет себя неподобающе
> head $ evenOnly [1..]
Interrupted.
Почему это происходит, и какие минимальные изменения можно в нее внести, чтобы восстановить утраченную работоспособность?
deniok: (пацифик)
Originally posted by [livejournal.com profile] vadim_i_z at Исполнилось сто лет со дня рождения Мартина Гарднера

Он прожил 95 лет и написал множество книгExpandвот лишь немногие из них )
А еще он комментировал Кэрролла и Честертона.
А еще несколько десятилетий вел отдел популярной математики в журнале «Scientific American».
А еще он открыл для многих творчество Мориса Эшера. И игру «Жизнь».
А еще он привел меня в профессию: именно его книги стали аттрактором, окончательно притянувшим меня к математике и физике.
Спасибо за всё, мистер Гарднер!
deniok: (typed lambda)
Доказать, используя Хаскель, что следующие тавтологии верны интуиционистски
(a -> c) /\ (b -> c) -> a \/ b -> c
(a \/ b -> c) -> (a -> c) /\ (b -> c)
(Понятно, что конъюнкция - это пара, а дизъюнкция - Either.)

UPD. Стоит напомнить, что изоморфизм Карри-Говарда имеет место между интуиционистской версией пропозициональной логики и подмножеством Хаскеля без рекурсии. То есть использовать рекурсию нельзя - ни явно, ни неявно. Ну и определение отрицания требует в Хаскелле некоторых хаков, но при доказательстве этих формул оно не требуется.
deniok: (пацифик)
Идиот
Дар
Колыбель для кошки
Петербург
Процесс
62. Модель для сборки
Солярис
Улитка на склоне
Петербургские повести
Чапаев и Пустота
deniok: (lambda cube)
Заказал на Озоне книжку Саймона Марлоу "Параллельное и конкурентное программирование на языке Haskell", переведенную уважаемым Виталием Брагилевским. Для рачительных и экономных сообщаю, что покупка на сайте издательства ДМК Пресс обойдется несколько дешевле.

Вот отзыв замечательного Романа Чепляки, правда на английскую версию.
deniok: (lambda cube)
Хорошая хотя и простая задачка возникла в процессе проверки домашних заданий. Чем отличается поведение следующих двух функций, и в чем причина такого отличия:
diff xs = do
    p <- zip xs (tail xs)
    return $ abs (fst p - snd p)

diff' xs = do
    p <- zip (tail xs) xs
    return $ abs (fst p - snd p)

Profile

deniok: (Default)
deniok

February 2022

S M T W T F S
  12345
6789101112
13141516171819
20212223 242526
2728     

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

Expand All Cut TagsCollapse All Cut Tags
Page generated Jun. 24th, 2025 08:25 pm
Powered by Dreamwidth Studios