Какова суета о Haskell? [закрытый]

У вас проблема с вашим DNS. Я уверен, что если вы сделаете:

$ ping deb.debian.org

Вы также получите ошибку.

Я бы порекомендовал вам прочитать это

109
задан 3 revs, 3 users 100% 1 May 2012 в 10:05
поделиться

17 ответов

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

Другая действительно интересная вещь в Haskell - это система типов. Он строго типизирован, но механизм вывода типов напоминает программу Python, которая волшебным образом сообщает вам, когда вы совершили глупую ошибку, связанную с типом. Сообщения об ошибках Хаскеля в этом отношении несколько отсутствуют,

132
ответ дан 24 November 2019 в 03:17
поделиться

Передать противоположный вид: бесполезный формальный математический смысл. Это обрабатывает несколько вычислительных конструкций очень хорошо; сопоставление с образцом отправка найдена в Haskell, SML и OCaml особенно удобен. Неудивительно, что он обрабатывает некоторые другие общие и весьма желательные конструкции в лучшем случае неловко, но они объясняют эти сценарии далеко, сказав, что вы ошибаетесь, вы на самом деле не хочу их. Вы знаете, такие вещи, как, о, установка переменных.

Haskell стоит изучить, но у него есть свои слабые стороны.

-1
ответ дан 24 November 2019 в 03:17
поделиться

он не имеет циклических конструкций. не многие языки имеют эту черту.

2
ответ дан 24 November 2019 в 03:17
поделиться

Если вы можете обернуть голову вокруг системы типов в Хаскеле, я думаю, что это само по себе довольно большое достижение.

3
ответ дан 24 November 2019 в 03:17
поделиться

Я согласен с другими, что увидеть несколько небольших примеров - не лучший способ показать Хаскель. Но я все равно дам немного. Вот молниеносное решение задач проекта Эйлера 18 и 67 , в котором вас попросят найти путь с максимальной суммой от основания до вершины треугольника:

bottomUp :: (Ord a, Num a) => [[a]] -> a
bottomUp = head . bu
  where bu [bottom]     = bottom
        bu (row : base) = merge row $ bu base
        merge [] [_] = []
        merge (x:xs) (y1:y2:ys) = x + max y1 y2 : merge xs (y2:ys)

Вот полная, многократно используемая реализация алгоритма BubbleSearch Леша и Митценмахера. Я использовал его для упаковки больших медиа-файлов для архивного хранения на DVD без потерь:

data BubbleResult i o = BubbleResult { bestResult :: o
                                     , result :: o
                                     , leftoverRandoms :: [Double]
                                     }
bubbleSearch :: (Ord result) =>
                ([a] -> result) ->       -- greedy search algorithm
                Double ->                -- probability
                [a] ->                   -- list of items to be searched
                [Double] ->              -- list of random numbers
                [BubbleResult a result]  -- monotone list of results
bubbleSearch search p startOrder rs = bubble startOrder rs
    where bubble order rs = BubbleResult answer answer rs : walk tries
            where answer = search order
                  tries  = perturbations p order rs
                  walk ((order, rs) : rest) =
                      if result > answer then bubble order rs
                      else BubbleResult answer result rs : walk rest
                    where result = search order

perturbations :: Double -> [a] -> [Double] -> [([a], [Double])]
perturbations p xs rs = xr' : perturbations p xs (snd xr')
    where xr' = perturb xs rs
          perturb :: [a] -> [Double] -> ([a], [Double])
          perturb xs rs = shift_all p [] xs rs

shift_all p new' [] rs = (reverse new', rs)
shift_all p new' old rs = shift_one new' old rs (shift_all p)
  where shift_one :: [a] -> [a] -> [Double] -> ([a]->[a]->[Double]->b) -> b
        shift_one new' xs rs k = shift new' [] xs rs
          where shift new' prev' [x] rs = k (x:new') (reverse prev') rs
                shift new' prev' (x:xs) (r:rs) 
                    | r <= p    = k (x:new') (prev' `revApp` xs) rs
                    | otherwise = shift new' (x:prev') xs rs
                revApp xs ys = foldl (flip (:)) ys xs

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

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

6
ответ дан 24 November 2019 в 03:17
поделиться

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

Например, если вы Если вы хотите вычислить все простые числа, вы можете использовать

primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x<-xs, x `mod` p /= 0]

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

foo = sum $ takeWhile (<100) primes

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

На самом деле это полезно не только для бесконечных списков он привыкает без вашего ведома, когда нет необходимости оценивать больше, чем необходимо.

7
ответ дан 24 November 2019 в 03:17
поделиться

Интересный пример, который вы можете посмотреть на: http://en.literateprograms.org/Quicksort_ (Haskell)

Интересно посмотреть на реализацию на разных языках.

Что делает Haskell таким интересным, наряду с другими функциональными языками, так это Дело в том, что вы должны думать по-другому о том, как программировать. Например, вы, как правило, не будете использовать циклы for или while, но будете использовать рекурсию.

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

11
ответ дан 24 November 2019 в 03:17
поделиться

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

17
ответ дан 24 November 2019 в 03:17
поделиться

Part of the fuss is that purity and static typing enable for parallelism combined with aggressive optimisations. Parallel languages are hot now with multicore being a bit disruptive.

Haskell gives you more options for parallelism than pretty much any general purpose language, along with a fast, native code compiler. There is really no competition with this kind of support for parallel styles:

So if you care about making your multicore work, Haskell has something to say. A great place to start is with Simon Peyton Jones' tutorial on parallel and concurrent programming in Haskell.

22
ответ дан 24 November 2019 в 03:17
поделиться

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

Когда оно приходит При написании программы для использования в реальном мире вам может показаться, что на Haskell не хватает практического подхода, но ваше окончательное решение будет лучше, если вы знаете Haskell с самого начала. Я определенно еще не там, но до сих пор изучение Хаскелла было намного более поучительным, чем, скажем, Лисп учился в колледже.

26
ответ дан 24 November 2019 в 03:17
поделиться

Вы как бы задаете неправильный вопрос.

Хаскель - это не язык, где вы смотрите на несколько интересных примеров и говорите: «Ага, теперь я вижу, , это , что делает его хорошим!»

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

  • Ленивая оценка
  • Никаких побочных эффектов (все чисто, IO / и т. Д. Происходит через монады)
  • Невероятно выразительная система статических типов

а также некоторые другие аспекты, которые отличаются от многих основных языков (но разделяются некоторыми):

  • функциональный
  • значительный пробел
  • выведенный тип

Как ответили некоторые другие авторы, сочетание всех этих особенностей означает, что вы думаете о программировании совершенно по-другому. И поэтому трудно придумать пример (или набор примеров), который адекватно сообщает об этом Joe-mainstream-programmer. Это опытная вещь. (Чтобы провести аналогию, я могу показать вам фотографии моей поездки в Китай в 1970 году, но после просмотра фотографий вы все равно выиграли » Не знаю, каково это было жить там в то время. Точно так же я могу показать вам «быструю сортировку» Haskell, но вы все равно не будете знать, что значит быть Haskeller.)

65
ответ дан 24 November 2019 в 03:17
поделиться

Я не могу дать Например, я парень из OCaml, но когда я нахожусь в такой ситуации, как вы, любопытство просто берет верх, и мне нужно скачать компилятор / интерпретатор и попробовать. Скорее всего, вы узнаете намного больше о сильных и слабых сторонах данного функционального языка.

7
ответ дан 24 November 2019 в 03:17
поделиться

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

1
ответ дан 24 November 2019 в 03:17
поделиться

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

Возможно, самой большой победой для меня стала возможность модулировать поток управления через такие вещи, как моноиды, монады и так далее. Очень простой пример - моноид Ordering; в таком выражении, как

c1 `mappend` c2 `mappend` c3

, где c1 и так далее, return LT , EQ или GT , c1 , возвращающий EQ , вызывает продолжение выражения с вычислением c2 ; если c2 возвращает LT или GT , это значение целого, а c3 не оценивается. Подобные вещи становятся значительно более изощренными и сложными в таких вещах, как генераторы монадических сообщений и парсеры, где я могу переносить различные типы состояний, иметь различные условия прерывания или, возможно, захочу решить для любого конкретного вызова, действительно ли означает прерывание. «без дальнейшей обработки» или означает «вернуть ошибку в конце, но продолжить обработку, чтобы собрать дальнейшие сообщения об ошибках».

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

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

18
ответ дан 24 November 2019 в 03:17
поделиться

Это пример , который убедил меня выучить Haskell (и я рад, что я это сделал).

-- program to copy a file --
import System.Environment

main = do
         --read command-line arguments
         [file1, file2] <- getArgs

         --copy file contents
         str <- readFile file1
         writeFile file2 str

Хорошо, это короткая, читаемая программа. В этом смысле это лучше, чем программа на C. Но чем это так отличается от (скажем) программы Python с очень похожей структурой?

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

Haskell «ленив». Он не вычисляет вещи до тех пор, пока это не нужно, и, соответственно, не вычисляет вещи, которые ему никогда не нужны. Например, если бы вы удалили строку writeFile , Haskell вообще не стал бы читать что-либо из файла.

Как бы то ни было, Haskell понимает, что writeFile зависит от readFile , и поэтому может оптимизировать этот путь данных.

Хотя результаты зависят от компилятора, при запуске вышеуказанной программы обычно происходит следующее: программа считывает блок (скажем, 8 КБ) первого файла, затем записывает его во второй файл, затем читает другой блок. из первого файла и записывает его во второй файл и так далее. (Попробуйте запустить на нем strace !)

... что очень похоже на то, что делает эффективная реализация копии файла на языке C.

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

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

  1. Лучший дизайн программы. Снижение сложности приводит к меньшему количеству логических ошибок.

  2. Компактный код. Меньше строк с описанием ошибок.

  3. Ошибки компиляции. Множество ошибок, просто недопустимы в Haskell .

Haskell не для всех. Но всем стоит попробовать.

136
ответ дан 24 November 2019 в 03:17
поделиться

Я считаю что для некоторых задач я невероятно продуктивен с Haskell.

Причина в лаконичном синтаксисе и простоте тестирования.

Вот как выглядит синтаксис объявления функции:

foo a = a + 5

Это самый простой способ определения функции, который я могу придумать.

Если я напишу обратный

inverseFoo a = a - 5

, я могу проверить, является ли он обратным для любого случайного ввода, написав

prop_IsInverse :: Double -> Bool
prop_IsInverse a = a == (inverseFoo $ foo a)

И вызов из командной строки

jonny @ ubuntu: runhaskell quickCheck + names fooFileName.hs

Что проверит, что все свойства в моем файле сохранены , путем случайного тестирования входных данных сто раз так.

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

5
ответ дан 24 November 2019 в 03:17
поделиться

Для меня привлекательность Haskell - это обещание гарантированной корректности компилятора. Даже если это для чистых частей кода.

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

5
ответ дан 24 November 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: