LINUX.ORG.RU

Сила Haskell

 ,


0

4

Встретил на хабре полную соплей восторга статеечку. Вот цитата из нее

Как Морфеус в «Матрице», fmap знает, что делать; вы начали с Nothing и закончите тоже с Nothing! Это fmap-дзен. И теперь понятно, для чего вообще существует тип данных Maybe. Вот, например, как бы вы работали с записью в базе данных на языке без Maybe:

post = Post.find_by_id(1)
if post
  return post.title
else
  return nil
end

На Haskell же:

fmap (getPostTitle) (findPost 1)

Если findPost возвращает сообщение, то мы выдаём его заголовок с помощью getPostTitle. Если же он возвращает Nothing, то и мы возвращаем Nothing! Чертовски изящно, а?

источник http://habrahabr.ru/post/183150/

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

base.post1.postTitle
будет то же самое, если нет поста, вернется undefined. В любом случае, в любом ЯП это тривиально, самое трудное, с чем можно столкнуться в реализации — это обработка исключения. Тогда почему он так возбудился? Почему эти адепты ФП сначала орут «Я вам покажу магию хаскела», а в итоге показывают позорную банальщину? Это гипноз чтоли?

Ответ на: комментарий от anonymous

умение внятно объяснить появляется у того, кто хорошо понимает предмет объяснения

да щааааз. прям вот берёт и магическим образом появляется. конечно.

next_time ★★★★★
()
Ответ на: комментарий от next_time

у того, кто не понимает предмет, немного шансов его объяснить

магическим образом

Магия Школьного Образования. Вам сочинения, наверное, не задавали еще. Вы, возможно, поэтому педагогику с риторикой перепутали.

anonymous
()
Ответ на: комментарий от dizza

Agda еще круче

Есть мнение, что зависимые типы в general purpose языках (а не proof assistant'ах) не нужны, потому что реализовать полноценную систему на зависимых типах с должной эффективностью невозможно, да и то, что есть уже может выглядеть жутко. Мнение высказывалось, емнип, в частности, Пирсом.

buddhist ★★★★★
()

Начинай свои посты про хаскель с фразы «Я ни**я не понимаю в хаскеле, но вот я подумал, что вот тут, наверное, говно».

Aswed ★★★★★
()
Ответ на: комментарий от buddhist

В некотором зачаточном виде зависимые типы есть в scala. Компилица такой код конечно долго, но есть инфа, что с появлением макросов ситуация улучшится, это если про general purpose говорить.

dizza ★★★★★
()
Ответ на: комментарий от anonymous

Спросил у компилятора.

Спрашивать у компилятора значение каждой строчки кода? Отличное решение!

Вот только проблема в том, что компилятору конкретный инстанс тоже узнать неоткуда. Там будет стоять просто функтор.

anonymous
()
Ответ на: комментарий от anonymous

Если компилятору не важно, какой инстанс функтора используется, то функция полиморфная и может использоваться с любым. Если компилятор из типа findPost вывел конкретный функтор, то он покажет его программисту в типе того конкретного fmap.

И да, спрашивать у компилятора типы ни разу не зазорно, он для того и существует.

anonymous
()
Ответ на: комментарий от anonymous

Откуда?

Это называется «статическая типизация» и «выведение типов».

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

Там будет стоять просто функтор.

Просто функтор - это тайпкласс. Там будет стоять инстанс этого тайпкласса. В конкретном случае - Maybe.

hateyoufeel ★★★★★
()

Почему эти адепты ФП сначала орут «Я вам покажу магию хаскела», а в итоге показывают позорную банальщину? Это гипноз чтоли?

Да, чувачок показал пример который легко перекрывается, с другой стороны там это видимо уже встроено(?).

umren ★★★★★
()
Ответ на: комментарий от anonymous

Если компилятору не важно, какой инстанс функтора используется, то функция полиморфная и может использоваться с любым.

Именно так. В результате нету никакого способа узнать, что тип аргумента - Maybe и, значит, понять, что эта функция делает.

Если компилятор из типа findPost вывел конкретный функтор, то он покажет его программисту в типе того конкретного fmap.

Он выведет конкретный функтор в месте аппликации. А речь об определении функции. Исправить это можно, руками указав более точный тип.

И да, спрашивать у компилятора типы ни разу не зазорно, он для того и существует.

Ну конечно не зазорно, ведь иначе код вообще понять будет нельзя. Смысл в том, что это на порядок замедляет чтение кода. Когда ты смотришь и видишь liftToMaybe то сразу ясно, что происходит, не надо куда-то лезть, что-то смотреть и т.п..

Если семантически ф-я предполагает, что там может стоять ЛЮБОЙ функтор - тогда да, надо ставить fmap. Но если ты знаешь, что тут именно проверка на Nothing - то следует упрощать чтение. Explicit при чтении кода практически всегда лучше, чем implicit.

anonymous
()
Ответ на: комментарий от hateyoufeel

Просто функтор - это тайпкласс. Там будет стоять инстанс этого тайпкласса.

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

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

anonymous
()
Ответ на: комментарий от anonymous

общим типом будет полиморфная ф-я, с произвольным инстансом функтора в качестве аргумента.

Может ты хотя бы пруф этого наркоманского бреда покажешь? Мне было бы крайне интересно посмотреть, потому что моя копия GHC подобной хрени почему-то не делает.

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

Если я и компилятор точно знаем, что там Maybe, то какой смысл использовать liftToMaybe? Чтобы потом при изменении Maybe на Either String нужно было поменять функцию еще в одном месте?

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

anonymous
()
Ответ на: комментарий от anonymous

Единственный юзкейс для мономорфных функций - пояснить компилятору какой инстанс использовать.

Для этого можно просто тип обозначить.

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous
Prelude> let getMaybe = undefined :: Maybe Int
Prelude> let addOne = (+) 1 :: Int -> Int
Prelude> :t addOne `fmap` getMaybe 
addOne `fmap` getMaybe :: Maybe Int
Prelude> :t flip fmap getMaybe 
flip fmap getMaybe :: (Int -> b) -> Maybe b

Не мог бы ты, анонимус-баклажан, пальцем показать, где здесь произвольный инстанс функтора?

hateyoufeel ★★★★★
()
Ответ на: комментарий от anonymous

Если я и компилятор точно знаем, что там Maybe, то какой смысл использовать liftToMaybe?

При чем тут ты и компилятор? Программист пишет код не для себя и не для компилятора, а для других программистов. И основная задача которую решает программист при написании кода - чтобы максимально ускорить понимание логики работы программы для других программистов.

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

Единственный юзкейс для мономорфных функций

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

Чтобы потом при изменении Maybe на Either String нужно было поменять функцию еще в одном месте?

Это уже ортогональные вещи. Тут претензии к кривому дизайну стандартной библиотеки хачкеля - по нормальному нужен тайплкасс, которому бы принадлежали все функторы, которые можно использовать в данном качестве (обработка ошибок).

anonymous
()
Ответ на: комментарий от hateyoufeel

Нет ты. Откуда возьмётся «произвольный инстанс» ?

Оттуда, что у компилятора нету никакой информации о том, какой инстанс выбрать. И получить компилятор эту информацию никак не может.

anonymous
()
Ответ на: комментарий от anonymous

Оттуда, что у компилятора нету никакой информации о том, какой инстанс выбрать. И получить компилятор эту информацию никак не может.

Говорю же тебе: ты баклажан. Если с одной стороны на вход fmap подаётся типа Maybe a, какой инстанс класса Functor нужно выбрать? Давай, подумай, это не так сложно.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Если с одной стороны на вход fmap подаётся типа Maybe a

Еще раз для непонятливых:

let yoba = fmap

Где и куда тут подается Maybe a? И какой, все-таки, тип у yoba? И, еще раз, это все совершенно несущественно. То, что делает код, должно быть (по крайней мере на верхнем уровне) понятно из самого кода. Ну то есть сразу, вот взглянул - и все ясно. Без вопросов к компилятору о типе. А код «я лифтанул ф-ю в какой-то функтор» - вообще никакой информации читающему не сообщает о логике своей работы.

anonymous
()
Ответ на: комментарий от anonymous

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

Тайпкласс, кстати, был в отдельном пакете (https://hackage.haskell.org/package/failure). Собственно, автор отказался от его использования, что говорит об его полезности в целом.

anonymous
()
Ответ на: комментарий от anonymous

Все ровно наоборот, нужно везде использовать максимально полиморфные функции.

Нет, смысл статической типизации - наиболее точно отразить семантику предметной области. И после того как описал - вспоминать о типах ты вообще больше не должен, по идее. Если вспоминать приодится - классический случай потекшей абстракции. А хочешь генерализованный код - пиши на динамике, там у всех ф-й бодрый тип Any -> Any, генерализованнее некуда.

Собственно, автор отказался от его использования, что говорит об его полезности в целом.

Это говорит лишь о культуре программирование в хаскель-комьюнити. Большинство вообще совершенно не стесняясь пишет поинтфри ребусы вместо кода, о чем тут говорить можно?

anonymous
()
Ответ на: комментарий от anonymous

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

Все помнят о типах. Просто ты - баклажан и унылый тролль. Троллируй лучше, ты можешь, мы верим в тебя.

Большинство вообще совершенно не стесняясь пишет поинтфри ребусы

Point-free ребусы намного читабельнее длинной простыни.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Все помнят о типах

Именно для того, чтобы о них напоминать, видимо, сделали тайп инференс, да? Ты просто не понимаешь, что такое система типов, для чего она нужна, и как с ней работать

Point-free ребусы намного читабельнее длинной простыни.

Ну да, читать их проще. Зато простыня почти всегда понятнее. И к тому моменту когда ты заканчиваешь разгадывание ребуса, в случае простыни обычно уже не только полностью понимаешь ее семантику - но уже успеваешь внести в нее нужные изменения.

Поинтфри ребусы, на самом деле, нечто вроде регекспов - то есть когда нужно что-то в них поменять, этим на практике никто не занимается, просто регексп (ребус) удаляется и пишется заново новый.

anonymous
()
Ответ на: комментарий от hateyoufeel

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

anonymous
()
Ответ на: комментарий от anonymous

у того, кто не понимает предмет, немного шансов его объяснить

1)не обязательно. он может внятно преподать основы, а остальное ученик сам разберёт

2)и как из этого следует то, что человек хорошо понимающий предмет имеет много шансов его объяснить?

next_time ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.