Можно ли использовать функции в параметрах Haskell? - PullRequest
4 голосов
/ 24 февраля 2012

Я видел несколько примеров кода на 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

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

Ответы [ 6 ]

13 голосов
/ 24 февраля 2012

То, что вы видели, - это особый тип сопоставления с образцом, называемый «n + k pattern», который был удален из Haskell 2010. Смотрите Что такое «n + k pattern» и почему они запрещены в Haskell 2010? и http://hackage.haskell.org/trac/haskell-prime/wiki/RemoveNPlusK

3 голосов
/ 25 февраля 2012

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

{-# LANGUAGE ViewPatterns #-}

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

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

2 голосов
/ 24 февраля 2012

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

foo (x:xs) = ...

где x - заголовок списка, а xs - остаток списка или

foo (x:[]) = 

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

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

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

Еще одна возможность - использование схемы «коммутационный шкаф»:

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

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

Чтобы исправить вашу проблему, я не думаю, что что-то из этого применимо, но почему бы не добавить определение функции catch-Остаток-значения-значения, например:

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

Надеюсь, это поможет,

Оливер

2 голосов
/ 24 февраля 2012

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

2 голосов
/ 24 февраля 2012

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

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

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

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

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

fibonacci :: Integer -> Integer
fibonacci n
| n == 0 = 0
| (n == 1 || n == 2) = 1
| otherwise = fibonacci(n-1) + fibonacci(n-2)    
1 голос
/ 24 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...