2009-08-01 1 views
13

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

+1

И еще одно должно быть-сообщество-вики ... – chaos

+0

Этот стиль вопроса обычно лучше оценивается как Wiki сообщества. – zombat

+0

Трудно представить себе, почему это «не настоящий вопрос», когда есть так много других «ошибок общего программирования» на SO, которые выжили. –

ответ

15

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

Другая распространенная ошибка Забудьте, что let всегда рекурсивно. Непреднамеренное

let x = ... x ... 

может привести к озадачивает результатов.

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

В целом трудности, с которыми сталкиваются начинающие Haskell программистов включают

  • Большой язык со многими темными углами, особенно в системе типа
  • проблемы при получении программ для компиляции, особенно когда они делают ввода/вывода
  • Выполнение всего в IO monad
  • Большая трудность, предсказывающая поведение времени и пространства ленивых функциональных программ
8

Общая ошибка для начало Программисты Haskell составляют forget the difference between constructor and type namespaces. Это была такая ошибка новичка, что я смущен тем, что мое имя привязано к ней, но я уверен, что другие наткнутся на этот ответ, когда у них возникнет аналогичная проблема, так что, возможно, также сохранится там.

4

Разница между [] и [[]]: пустым списком и списком с 1 элементом, а именно пустым списком. Это особенно всплывает в базовых случаях рекурсивных функций.

-1

Используйте не-хвостовые рекурсивные функции или не строгие складки, возникающие при переполнении стека.

+2

Это менее верно в Haskell, чем в других функциональных языках. В большинстве случаев, ленивость делает ненужные версии функций более предпочтительными (например, вы можете 'foldr' бесконечный список, в то время как tail-recursive' foldl' будет взорваться каждый раз). – Chuck

+1

Я знаю это, но head (x: xs) = head xs + 1 не будет взорваться в списке из 1000000 предметов? – Hai

+0

Я пробовал 'head '' (x: xs) = let x '= head' 'xs in x' \' seq \ 'x '+ 1', без успеха. У кого-нибудь есть подсказки? – ScootyPuff

-1

Понятие выражения довольно запутанно для новичков. Возьмите условную конструкцию на языках императивного программирования. Там его просто конструкция, но в Haskell - это выражение. Таким образом, условие if должно иметь соответствие else, и оба должны давать значения одного и того же типа оценки.

wrongFunc n = if n > 18 
       then 1 
       else False 

Блок if вычисляет целое число, когда else возвращает bool. Это обычная ошибка, так как в Haskell они не просто блок выражений, а выражения.

+3

Я не понимаю, почему это сбивает с толку, и я немного новичок Haskell. Сравните то же самое на языке C-типа: у вас есть явные возвращения, но тип возврата должен быть либо int, либо bool, и было бы ошибкой возвращать 1 или false в зависимости от значения аргумента. – Zak

Смежные вопросы