Pull to refresh
100
0
Arthur Welf @art_of_press

User

Send message
Рекурсивное, однако весьма эффективное определение последовательности чисел Фибоначчи. Функция высшего порядка zipWith берет два списка и применяет к их элементам с одинаковыми указанную функцию (в данном случае — функцию сложения):

fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
Если пытаться прогнозировать будущее, то лучше всего смотреть на то, что и как делают дети и подростки. Так вот: если посмотреть, что и как они делают, то можно увидеть, что они в качестве основной используют мобильные платформы (подростки — в основном телефоны, а детки помладше — в основном планшеты), а на них — нативные, а не браузерные, приложения. Это наблюдение подтверждается в том числе теми моими знакомыми, которые развивают детские ресурсы — все они сейчас озабочены тем, как их устоявшуюся бизнес-модель перенести в мир нативных приложений на мобильных устройствах.
Я не говорю, что вы не должны знать физику вообще. Но для управления самолетом вам не нужно знать физику в объеме, который необходим для создания вами самолета.
Если брать конечный результат, то да — разницы между циклами и рекурсией никакой. Но если рассматривать то, каким образом этот результат достигается, то разница есть: в циклах вы оперируете на уровне каждого отдельного значения в коллекции, а в рекурсии вы оперируете на уровне коллекции целиком. То есть разница — в уровне абстракции. Как современные императивные языки абстрагируются от машинного кода, так и функциональные языки абстрагируются от уровня отдельных элементов коллекции.
Попытаюсь вам объяснить. Но для этого вам нужно попытаться переформулировать свой вопрос «В какой конкретной задаче мне может помочь функтор?» и сформулировать его на более высоком уровне абстракции: «Как функторы могут мне помочь в программировании вообще?» (т.е. в решении любых задач, а не какой-то конкретной).

Что такое функторы, монады и прочие концепции в Haskell? Это шаблоны, которые реализованы в языке для того, чтобы нам было легче решать различные классы задач:

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

Но что, если нам нужно выйти за пределы «чистых» функций? Например, нам нужен определенный порядок вычислений (то есть одна функция должна знать, вычислена ли другая функция или нет). Или мы взаимодействуем с внешним миром, и в качестве результата выполнения нашей функции мы можем получить не одно, а много разных значений (недетерминированные вычисления). Или нам нужно «тащить» за собой, помимо результата функции, некое состояние. Для всех этих случаев, когда у значения результата наших функций есть некий «контекст», как мы это называем, Haskell предлагает нам использовать определенный шаблон — монады. При помощи этого шаблона мы можем унифицированно работать со всеми случаями, когда у нас имеется значение плюс какой-то контекст (мы обычно называем это значением, «обернутым» в контекст).

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

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

Можно ли программировать на Haskell, не зная или не понимая этих концепций? Да, можно. Но их знание и понимание облегчает программирование.

Нужно ли знать и понимать математические теории, лежащие в основе монад, функторов и т.д., чтобы понять их? Совсем не обязательно. Эти математические теории помогли создать эти языковые концепции, но вы же можете научиться управлять самолетом, не изучая всю ту физику, которая помогла создать летательные аппараты? Конечно. То же самое и здесь.

Монады, функторы, аппликативные функторы, функции васшего порядка — это все не алгоритмы, а некие универсальные шаблоны, концепции, которые мы можем использовать для того, чтобы писать меньше кода и сделать наш код более читабельным.

И позвольте, в заключение, «перевести» некоторые ваши вопросы на «ООП-язык», чтобы вы лучше поняли, что рассматриваемые понятия — это не алгоритмы, а концепции:

То, что мы можем ввести классы объектов… Ну. Замечательно. Но что с того? Если я пишу, допустим, текстовый редактор, как это мне поможет?


Повторюсь: вот пишу я текстовый редактор, где мне могут пригодиться классы объектов?


Интересным был бы пример какой-нибудь такой: допустим, нам надо посчитать спектр матрицы, объекты помогут нам в этой задаче так-то и так-то. Ну, или не знаю… При перемножении больших чисел через преобразование Фурье. Ну, то есть, в задаче, где есть реальные проблемы со сложностью кода. Было бы неплохо показать, в каком месте объектный подход срабатывает лучше теории типов.


Надеюсь, стало понятнее ;)).
Вообще, одно из главных отличий функциональных языков от императивных, которое нужно понять, и которое обычно мешает императивщикам приучиться мыслить в функциональном стиле — это оперирование в терминах коллекций значений, а не на уровне отдельного значения в коллекции. То есть нужно перейти на более высокий уровень абстракции. Именно поэтому в функциональных языках нет циклов (потому что там вы думаете, что нужно сделать с каждым отдельным элементом коллекции), но есть функции высшего порядка, которые работают с коллекциями целиком.

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

instance Functor [] where 
fmap = map
Практический смысл функторов объяснить очень просто. Смысл в повторном использовании функций, которые у нас уже определены.

1. У нас есть нумерические типы (Int, Integer, Double, Float), для которых уже определена функция сложения (+).

2. У нас есть «обертки» для нумерических типов (например, список нумерических значений [1, 2, 3, 4], или значение Just 5 типа Maybe).

3. При помощи функтора fmap мы можем повторно использовать уже имеющуюся у нас функцию сложения (+) для «обернутых» нумерических значений, вместо того, чтобы писать новую функцию:
fmap (+ 1) [1, 2, 3, 4]
> [2, 3, 4, 5]

fmap (+ 1) (Just 5)
> Just 6


Применив «обертку» к типу А, мы, тем самым, получили новый тип Б. Тем не менее, мы можем, при помощи функторов, применять функции, определенные для типа А, к значениям типа Б.

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

Сейчас процесс образования выглядит так:

1. Преподаватель в классе дает ученикам теорию, и на паре примеров показывает, как решать задачи при помощи того, что ученики узнали из теоретической части.

2. После лекции/урока ученики самостоятельно закрепляют пройденный материал, выполняя заданное преподавателем домашнее задание.

На основании опыта Khan Academy и результатов пилотного проекта академии с одной из школ, Салман Хан предлагает кардинально видоизменить процесс обучения.

По его мнению, образовательный процесс гораздо эффективнее проходит в такой конфигурации:

1. Теоретическая часть записывается преподавателем на видео, и учащиеся самостоятельно изучают ее перед уроком. Т.е. домашним заданием является не решение задач, а изучение теоретической части путем просмотра видеолекции.

2. На уроке же преподаватель задает ученикам задачи для закрепления теории, которую те прошли дома. При этом учащиеся обмениваются мнениями о предлагаемых ими способах решения задач, а преподаватель находит и разъясняет нюансы, которые, как выясняется, остались не совсем понятыми, а также помогает ученикам выбрать наиболее эффективный способ решения задачи из предложенных ими способов.

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

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

При этом совместная работа преподавателя с учениками в классе над заданиями позволяет установить между ними лучший контакт, а также позволяет преподавателю получить более полное представление о том, насколько хорошо учащиеся усвоили материал, и в чем именно необходимо «подтянуть» каждого конкретного ученика.
Вероятно, в низкой активности продавцов по снижению цены на низкомаржинальный товар. Когда заявки были на люксовые ноуты типа Асуса Ламборгини, то продавцы действительно старались и торговались за нее (цены снижались на $1 тыс. по сравнению с минимальной ценой на я.маркете). А вот по низкомаржинальным товарам активность борьбы продавцов за заказ была недостаточной.
Обязательна, увы. При такой бизнес-модели покупатели ожидают реального торга за свои заявки, иначе остаются неудовлетворенными (и дело даже не в цене, а, скорее, во внимании, которое они ожидают, хотя на более высокую цену они тоже не согласны). Поэтому эта модель работает только на рынке, где по всем (!) товарам абсолютный размер маржи очень высок. Покупатор работал на рынке электроники и бытовой техники, и там по большинству моделей абсолютный размер маржи очень низок. Когда были заявки на люксовые товары, модель работала хорошо, но по большинству моделей и, тем более, аксессуарам — увы, не работала.
Эта бизнес-модель работает на очень немногих рынках. На рынке шоколадок точно не работает. А работает только там, где абсолютная величина маржи при продаже 1 единицы товара оправдывает ручную обработку нескольких заказов менеджером. Например, при продаже автомобилей. Поверьте, я знаю, о чем говорю.
Моя личная позиция по сфере реформы образования такова:

1. Необходимо перестать финансировать ВУЗы. Т.е. ВУЗы должны учить людей на платной основе.

2. Деньги, которые раньше шли на финансирование ВУЗов, нужно распределять среди n лучших выпускников школ (можно еще выделить m лучших выпускников-льготников, типа сирот, детей погибших военнослужащих, инвалидов, отслуживших по контракту в армии для получения возможности учиться и т.д.) в виде образовательных сертификатов разной стоимости (в зависимости от набранных им баллов на том же ЕГЭ), которые они сдают в ВУЗы, а те обменивают у государства на живые деньги.

3. Если у человека есть сертификат, но его номинала не хватает на обучение в выбранном им ВУЗе, то часть своего обучения он может оплатить сертификатом, а то, что не хватает, должен оплатить самостоятельно.

4. В качестве ВУЗа для обучения обладатель сертификата может выбрать не только российский ВУЗ, но и любой другой, входящий, скажем, в ТОП-250 мировых ВУЗов. Схема такая же — человек предоставляет сертификат, ВУЗ предъявляет его для погашения государству, государство переводит деньги на счет ВУЗа.

В результате такой реформы неконкурентноспособные ВУЗы загнутся, а конкурентноспособные соберут у себя лучших преподавателей (иначе к ним не пойдут учиться). Если хороших преподавателей будет не хватать, то их пригласят из-за границы (как того же Эйлера в свое время). Откашивать от армии с помощью столь дорогостоящей процедуры будет просто невыгодно. Отбывать номер по настоянию родителей и не учиться — тоже.
Да там все уровня Getting Started, т.к. эти дисциплины читаются на первых курсах. Неплохо, конечно, знать химию, но это тоже не критично — так же, как для программиста неплохо было бы знать высшую математику, но в принципе, в большинстве задач можно обойтись и без познаний в оной.

Я учился очень давно, так что названий учебников уже и не помню, если честно. Помню, что по биохимии смотрел трехтомник Ленинджера, но не помню точно, по нему ли я учил, или по учебнику другого автора (но помню, что учил как раз по трехтомнику ;)). В любом случае берите только иностранные учебники и не бойтесь их объема — в классных учебниках обычно все так подробно расписано, что учиться очень легко, а стиль изложения авторов отечественных учебников можно сравнить лишь со стилем изложения информации чиновниками ;).

Плюс посмотрите соответствующие курсы на той же Coursera или на других образовательных ресурсах. Подозреваю, что они там также весьма неплохи и доступны для понимания.
Иностранцы платят деньги за обучение в ВУЗах, выбирают дисциплины, которые они хотели бы изучить, не идут в ВУЗы ради отсрочки от армии и у них нет родителей, которые вдалбливают им, что «без высшего образования ты будешь никем», развивая комплекс лузера у того, кто не сумел поступить или не захотел учиться. Поэтому там на лекции ходят те, кто сознательно решил, что ему надо пройти этот курс.
Я школу закончил в 1990-м, поэтому меня влекли не медицина и IT, а медицина и математика ;).

Если вам нужно разобраться в фундаментальных основах медицины, то я бы посоветовал изучить гистологию, биохимию и общую физиологию (в перечисленном порядке). Почти все остальное в медицине (кроме хирургии) — производное от этого, и если вы хорошо понимаете основы, то все остальное выводится путем логических размышлений — от фармакологии до дифференциальной диагностики. Каждый курс в медицинском институте изучался в мое время в течении года (наряду с кучей других предметов), это не так много. Даже в те годы мне удавалось достать хорошие переводные учебники, которые позволяли не зазубривать, а понимать, что и почему происходит (все очень логично на самом деле), институтские учебники я попросту не открывал, лекции слушал только у одного профессора, который преподавал общую физиологию (реально хороший профессор был), но знал предметы не только лучше сокурсников, но и лучше подавляющего большинства преподавателей. Самостоятельно изучить эти предметы, имхо, требует не так уж много времени и сил. Освоить программирование на приличном уровне сложнее.
Мне кажется, что разделение людей по принципу «технарь/гуманитарий» ведет к неправильному пониманию того, как их обучать. Было бы более логично разделить людей на имеющих индуктивный (bottom to top) и дедуктивный (top to bottom) типы мышления.

Первым привычно мыслить на уровне «кирпичиков», постепенно строя из них программу, как это принято в императивных языках программирования. Вторым же привычен способ мышления от общего к частному, разбивая общую задачу на подзадачи, пока они не придут к тем же самым «кирпичикам». Именно такой подход свойственен разработке на функциональных языках программирования. Нельзя сказать, что один подход чем-то лучше другого, лучше говорить о том, какой подход лучше подходит тому или иному обучающемуся.

У меня, например, ярко выражен способ мышления top to bottom. Я легко представляю себе способ решения задачи, не представляя себе отдельные кирпичики, на которых будет построено решение. Но разбивая задачи на подзадачи (какие входящие аргументы мне нужно получить в основную функцию, чтобы она могла совершить вычисления? ок, пусть эти аргументы передают нам отдельные функции, а теперь подумаем, какие аргументы нам нужны уже для них, и откуда мы их можем получить — и так далее), я, в итоге, добираюсь до тех самых «кирпичиков».

В свое время я долго выбирал, куда же мне пойти учиться после школы — на мехмат, или же в медицинский, так как меня привлекало и то, и другое. В итоге выбрал второй вариант (о чем частенько жалею, кстати). Мышление top to bottom помогало мне как эффективно находить решения математических задач, так и в изучении естественных наук (к слову, и медицина, и биология относятся не к гуманитарным наукам, а к естественно-научным дисциплинам; называть людей, которые изучают белки и ДНК гуманитариями — это то же самое, что относить к гуманитариям, скажем, физиков).
Вписывая правильные слова, вы помогаете оцифровывать отсканированные книги. Вот отличный спич на TED человека, который придумал это.

Information

Rating
Does not participate
Date of birth
Registered
Activity