Функции в Хаскеле - PullRequest
       55

Функции в Хаскеле

3 голосов
/ 12 апреля 2011

Я новичок в функциональном программировании.У меня есть основной вопрос.

Я использую интерпретатор Хугса,

Я хотел бы написать функцию на Хаскеле;Я прошел несколько учебных пособий, но не получил его.

fact :: Int -> Int
fact n = if n == 0 then
1
else
n * fact (n-1)

Это дает мне синтаксическую ошибку: -S

ERROR - Syntax error in input (unexpected `=')

Ответы [ 4 ]

6 голосов
/ 12 апреля 2011

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

Вам необходимо поместить определения функций и т. Д. В модули, а затем загрузить их с помощью (например) :load fact.hs. В частности, есть ресурсы для Hugs, которые предоставляют больше информации по этой и другой теме (я использовал http://cvs.haskell.org/Hugs/pages/hugsman/index.html, чтобы проверить свои предположения).

Также обратите внимание, что отступ имеет значение, поэтому код не будет работать так, как вы разместили его здесь, даже если он находится в модуле. Эти учебники будут иметь правильные версии. Если нет, то они бесполезны, и вы должны их забыть.

4 голосов
/ 12 апреля 2011

Синтаксис неверен.В Haskell пробел имеет значение, как и в Python.Более конкретно, если у вас есть текст, который начинается в первом столбце строки, интерпретатор будет думать, что это объявление верхнего уровня.Правильный синтаксис был бы (например):

fact :: Int -> Int
fact n = if n == 0
  then 1
  else n * fact (n-1)

Вы также можете поместить if в одну строку, если хотите.Поэтому, если вы используете интерактивное приглашение, вы можете сделать:

λ> let fact n = if n == 0 then 1 else n * fact (n-1)

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

fact :: Int -> Int
fact 0 = 1
fact n = n * fact (n-1)

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

1 голос
/ 13 апреля 2011

Следует отметить, что наиболее элегантный способ написания этой функции:

fac n = product [1..n]

Подробнее см. http://www.willamette.edu/~fruehr/haskell/evolution.html.

1 голос
/ 12 апреля 2011

Создайте файл с именем, например, fact.hs

-- copying cedric's nicely formatted code
fact :: Int -> Int
fact n = if n == 0
    then 1
    else n * fact (n-1)

Это все, что действительно должно быть там. Если вы хотите сделать настоящие модули, вам нужно сделать кое-что еще.

Теперь откройте ghci из той же папки. В приглашении ghci используйте команду :l для загрузки «модуля»

Prelude> :l fact.hs
[1 of 1] Compiling Main             ( fact.hs, interpreted )
Ok, modules loaded: Main.
*Main> fact 3
6
*Main> fact 10
3628800

Я предполагаю, что это очень похожий процесс с Хагсом. Я думаю, что объятия требуют, чтобы имя файла было написано с большой буквы. ghci просто создает модуль «Main» и помещает в него ваш код; поэтому приглашение меняется с Prelude> на *Main>

Когда я работаю над небольшими функциями на Haskell, я обычно держу два открытых терминала: один для vim и один для ghci. Когда я изменяю файл в vim (и сохраняю его), я просто использую :r в ghci для перезагрузки новых определений.

*Main> :r
Ok, modules loaded: Main.
...