2012-02-24 2 views
4

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

пример:

-- Compute the nth number of the Fibonacci Sequence 
    fib 0 = 1 
    fib 1 = 1 
    fib (n + 2) = fib (n + 1) + fib n 

Когда я пытаюсь это, я получаю эту ошибку:

Parse error in pattern: n + 2 

Является ли это плохой пример? Или мне нужно сделать что-то особенное, чтобы сделать эту работу?

+0

Возможно, это представляет интерес? http://stackoverflow.com/questions/3748592/what-are-nk-patterns-and-why-are-they-banned-from-haskell-2010 – gspr

+3

Эти так называемые (n + k) шаблоны были запрещены из Haskell некоторое время назад. Замените третью строку следующим образом: 'fib n = fib (n - 1) + fib (n - 2)'. – Vitus

+0

NB Существует другой способ увидеть вызовы функций в левой части уравнения: [ViewPatterns] (http://hackage.haskell.org/trac/ghc/wiki/ViewPatterns). Я довольно удивлен, что они не более распространены. –

ответ

1

С (+) - это функция, вы не можете сопоставить шаблон с ней. Чтобы сделать то, что вы хотели, вам нужно будет изменить третью строку следующим образом: fib n = fib (n - 1) + fib (n - 2).

2

Постараюсь помочь, будучи в общей сложности новичку в Хаскелле.

Я считаю, что проблема в том, что вы не можете сопоставить (n + 2). С логической точки зрения любой аргумент «n» никогда не будет соответствовать «n + 2», поэтому ваше третье правило никогда не будет выбрано для оценки.

Вы можете переписать его, как Майкл сказал, чтобы:

fib n = fib (n - 1) + fib (n - 2) 

или определяют весь fibonnaci в функции с помощью охранников, что-то вроде:

fibonacci :: Integer -> Integer 
fibonacci n 
| n == 0 = 0 
| (n == 1 || n == 2) = 1 
| otherwise = fibonacci(n-1) + fibonacci(n-2)  
+0

Я думаю, вы имеете в виду * охранники *, а не соответствие шаблону в вашем последнем примере. – gspr

+0

Действительно, я, как сказал ... новичок, и я в конечном итоге злоупотреблял языком. Спасибо. – pcalcao

2

Схема согласовани ограничена в Функции конструктора. Поэтому, если вы можете сопоставлять аргументы функций, таких как (:) (список constrcutor) или Left и Right (конструкторы Either), вы не можете сопоставлять арифметические выражения.

2

Я думаю, что нотация fib (n+2) = ... не работает и является синтаксической ошибкой. Вы можете использовать «регулярное выражение» соответствие стиля для paramters, как списки или кортежи:

foo (x:xs) = ... 

где х глава списка и хз оставшейся части списка или

foo (x:[]) = 

который сопоставляется если список имеет только один элемент слева и который хранится в x. Даже сложные совпадения, такие как

foo ((n,(x:xs)):rg) = ... 

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

Другой возможностью является использование схемы «переключатель-случай»:

foo f x | (f x) = [x] 
foo _ _ = [] 

В этом случае элемент «х» заворачивают в списке, если условие (f x) верно. В других случаях параметры f и x не интересны и возвращается пустой список.

Чтобы устранить проблему, я не думаю, что любой из них применим, но почему бы не бросить в определении функции Catch-остальной-параметр-значение, как:

fib n = (fib (n - 1)) + (fib (n - 2)) 

Надеется, что это помогает ,

Оливер

3

Как уже упоминалось Томас, вы можете использовать Просмотр шаблонов для достижения этой цели:

{-# LANGUAGE ViewPatterns #-} 

fib 0 = 1 
fib 1 = 1 
fib ((subtract 2) -> n) = fib (n + 1) + fib n 

Из-за двусмысленности - в этом случае вам нужно использовать функцию subtract.

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