All streams
Search
Write a publication
Pull to refresh
69
0
Владимир @Googolplex

Software engineer

Send message
Интересно, почему в статье назвали интерфейсы с default-методами функциональными? Функциональный интерфейс — это просто интерфейс, у которого есть один абстрактный метод, вот и всё. default-методы к функциональности интерфейса непосредственного отношения не имеют.
Для любого q существует !q такое, что m(S[0] → S[1], q) = m(S[1] → S[0], !q).
Заклинание !q называется обратным для q.

Немного сомнительное предположение. Почему количество маны на обратное превращение будет совпадать с количеством на прямое превращение?
Завидую тем, кто может позволить себе работать с новыми версиями всех этих API…
Книга, конечно же, нужна.
Спасибо за ссылки, как-то пропустил это в своём кругозоре.
Ну и это же не с пяти метров! И карты, я думаю, всё-таки специальные, в отличие от симок, куда никто не будет вставлять нужную начинку.
Ну бред же. Какое бесконтактное считывание симки, вы что? Это же вполне определённый стандарт, не предусматривающий никакого беспроводного доступа. В банковских картах с чипом что-то похожее, и что, теперь карточки стало можно дистанционно считывать?
апокалиптический удар

это как?

Ну а в целом третий миф действительно похож на миф, потому что для достижения критической массы куски урана надо, грубо говоря, сложить вместе. Вспомните, как работали первые атомные бомбы.
Большое спасибо за статью!
К сожалению, очень не хватает информации по разработке плагинов к идее. Никакой полноценной информации по API идеи нет, а лазить в чужом коде и пытаться понять, что там к чему, очень трудно.
Мм, Pentadactyl это эмулятор Vim'а в файрфоксе. В виме gg это стандартная комбинация перехода к началу файла. Также, например, G — это переход к концу страницы)
Выбрал «Не пользуюсь кнопкой наверх, всегда прокручиваю вручную», потому что так делаю на мобильных девайсах. На десктопах у меня Firefox+Pentadactyl, где переход наверх делается комбинацией gg.
Имхо, стоило добавить вариант «Другое»)
Трейдеры готовы тратить сотни миллионов долларов на прокладку кабелей, сокращающих пинг на 6 миллисекунд. Для моделирования финансовых рынков используются суперкомпьютеры, составлением алгоритмов для торговых роботов заняты лучшие математики и программисты мира

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

Тем не менее, видео в посте весьма впечатляют.
1. Почти. В той статье Map объявлен только для Maybe, а хаскеллевский fmap работает с любым функтором.
2. Это зависит от того, что вы понимаете под «достать» и от вида «коробки». Если вы имеете в виду, можно ли написать функцию вида Monad m => m a -> a, то в общем случае нельзя. Как вы справедливо заметили, из Nothing доставать нечего. А из IO тем более просто так ничего достать не получится, сайд-эффекты во все поля.

Однако для конкретных монад/функторов вполне могут быть доступны возможности извлечь значение из «коробки» либо выполнить какие-нибудь действия, если это невозможно. В любом случае этот процесс «доставания» сведётся к pattern matching, потому что в конечном итоге любой тип данных в хаскелле есть алгебраический тип данных, а для них естественным способом «деконструкции» является как раз паттерн матчинг. Например, ответ на ваш вопрос про Maybe может выглядеть вот так:
someFunction m = case m of
  Just v -> ...  -- Maybe и в самом деле содержит значение; в этой ветке оно теперь доступно под именем v
  Nothing -> ...  -- Значения нет, делаем что-то другое, например, используем дефолтное


Однако сила монад и функторов, на самом деле, не непосредственно в возможности извлечь оттуда значение, а в наличии огромного количества комбинаторов. Например, для Maybe существует комбинатор maybe :: b -> (a -> b) -> Maybe a -> b, который определён примерно так:
maybe def f m = case m of
  Just v -> f v
  Nothing -> def

С его помощью очень удобно обрабатывать Maybe-значения.

Есть общие комбинаторы, вроде >>= и <*>, есть и частные, типа maybe. Они позволяют очень точно, чётко и ясно выражать различные действия внутри монад и функторов.

Любую другую монаду/функтор (кроме IO, но это, понятно, отдельная история), вообще говоря, можно «разобрать» на части с помощью паттернматчинга. Конечно, если автор библиотеки не стал экспортировать конструкторы своей монады/функтора, то пользователи этой библиотеки не смогут её «разобрать» непосредственно, но в таком случае автор, как правило, предоставляет другие возможности получить значение из «контейнера», если это вообще можно сделать в принципе.
Вот тип основной операции аппликативного функтора:
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b

А вот тип основной операции монады (только с другим порядком аргументов):
flip (>>=) :: (Monad f) => (a -> f b) -> f a -> f b

Эти операции похожи, но, очевидно, разные. Вторая операция «мощнее» первой, т.е. <*> можно выразить через >>=, а вот наоборот — нет.

Если чуть подробнее, то первая операция работает только с «чистыми» функциями, т. е. в случае аппликативного функтора вы можете совершать над элементами «контейнера» только операции без побочных эффектов (т.е. операции, которые никогда не могут вернуть сам «контейнер»). Монада же позволяет применять к значениям внутри «контейнера» любые операции, в том числе и с побочными эффектами (т.е. возвращающие «контейнер» того же рода).

Если ещё более подробно, то монада позволяет «схлопывать» два уровня «контейнера», т.е. для монад можно определить функцию
join :: (Monad m) => m (m a) -> m a
Наличие такой функции, в целом, и обеспечивает возможность применять к значениям в «контейнерах» операции с побочными эффектами. А вот для аппликативных функторов такую функцию определить нельзя.

Пример с Maybe здесь наиболее иллюстративен. Так как Maybe является монадой, то вы можете написать такое (здесь все операции возвращают Maybe):
do result1 <- someFailingOperation1
   result2 <- someFailingOperation2
   result3 <- someFailingOperation3 result2
   someFailingOperation4 result1 result3

или, эквивалентно,
someFailingOperation1 >>= \result1 ->
  someFailingOperation2 >>= \result2 ->
  someFailingOperation3 result2 >>= \result3 ->
  someFailingOperation4 result1 result3


Причём за счёт свойств монады Maybe, описанных в статье, такая цепочка операций вернёт Nothing, если хотя бы одна операция вернула Nothing. Заметьте, что здесь мы применяем someFailingOperation{3,4} к результатам предыдущих операций.

Если бы Maybe был бы только аппликативным функтором, но не монадой, то такого мы бы написать не смогли: в случае аппликативных функторов функции внутри контекста не могут возвращать сам аппликативный функтор. Вернее, они могут, но тогда мы получим два уровня вложенности контейнеров, а «схлопнуть» их не получится, что делает невозможным их сколько-нибудь осмысленное применение.
Спасибо большое, замечательный перевод! Особенно порадовала картинка «наблюдающего аппликативного функтора»)

Небольшое замечание:
Функтор — это тип классов.

Type class переводится скорее как «класс типов», тип классов = type of classes же.
При первом запуске демон создаст в «хомяке» директорию .conconky

IMO создавать каталог с конфигурацией в $HOME, когда есть $XDG_CONFIG_HOME = ~/.config не есть хорошо. Есть даже такая библиотека, которая исправляет поведение нехороших программ.
Для справки, третий вариант — значения, зависящие от типов — это просто полиморфизм. Лучше всего это продемонстрировать на языке типа хаскеля. Например, значение (вернее, не значение, а терм) 10 в зависимости от своего типа может быть разным. Например, 10 :: Int даёт целое число 10, 10 :: Double даёт число с плавающей точкой 10.0, 10 :: Complex Double может дать комплексное число 10 + 0i, 10 :: YourType может дать некоторое значение типа YourType, если для этого типа реализован класс типов Num. То есть, в зависимости от того, какой тип мы приписываем литералу (или другому терму, переменной, например), у него будет cвоё значение.
Ваш первый пример зависимого типа правильный, а второй — нет (второй пример ближе к структурным типам, как, например, интерфейсы в Go).

На самом деле, зависимые типы на самом верхнем уровне достаточно простая концепция. Пусть у вас есть тип List<T>. В таком случае тип List можно рассматривать как функцию над типами (вы даёте List тип, например, String, и получаете обратно тоже тип, List<String>). Это типы, параметризованные типами — система \lambda \omega.

Теперь представьте, что вы параметризуете тип не другим типом, а каким-либо значением — числом 10, строкой "string", каким-нибудь объектом. Например, если Vector<N> обозначает список чего-то длиной N, где N — натуральное число: Vector<10>, то тип Vector является зависимым типом. Система типов для лямбда-исчисления, которая позволяет такое делать, и есть \lambda P.
Если сравнивать конус из статьи и цилиндр с вики, то видно, что это не L, а именно V.
Кстати, K в CMYK так называется, потому что это Key — ключевой цвет. Он может быть и другим, не чёрным.
А светлота — это забавно) Это же brightness — просто яркость.
В целом статья интересная, спасибо.
Да, принцип инверсии контроля очень полезен и, кроме того, справедлив в любых объектно-ориентированных языках. Очень жаль, что очень много программистов про него забывают :( после них приходится такое разгребать, что удивляешься, как это вообще можно было написать, и как готовая программа в принципе работает.
Представьте, гироскоп, и акселерометр, датчик магнитного поля в устройстве за относительно не большие деньги, откуда и зачем такая щедрость?
и зачем такая ювелирная точность? Вряд ли для пользователей, и вряд ли для игр.

Представьте себе, эти качественные датчики сами по себе дешёвые. Цену на них не занижают — это не является «щедростью». А поскольку качественные датчики дешёвые, почему бы производителю планшетов и не поставить качественные датчики? Это просто технический прогресс. А чем лучше датчики, тем лучше работают приложения, их использующие — игры, компасы, шагомеры и прочее.

Приложение сможет создавать фотографии и видеоролики с помощью камеры в любое время без вашего разрешения.

Как вам уже сказали здесь несколько раз, «без вашего разрешения» есть артефакт перевода. Просто так камера смартфона никогда не включится, как и микрофон, как и прочая периферия. Они включаются только тогда, когда этого требует конкретное приложение, причём это приложение обязано продемонстрировать вам, что оно сейчас делает. Снятие данных с камеры без индикации этого невозможно — почитайте документацию для разработчиков Android или исходный код самой системы.

Напомню вам — исходники самой системы Android открытые. Никто бы не допустил возможности того, чего вы так боитесь, в коде системы. От гугла в готовых смартфонах только приложения, такие, как маркет или G+, которые пользуются открытой системой. Они в принципе не способны её обойти.

Information

Rating
Does not participate
Location
Santa Clara, California, США
Date of birth
Registered
Activity