2014-11-18 4 views
0

У меня проблема с Haskell, где, похоже, не нравится тот факт, что я возвращаю булево утверждение из вспомогательной функции , Я проверяю, является ли расстояние между двумя числами в списке очень маленьким (менее 0,01); и в случае, когда это правда, я возвращаю это число. В случае, когда он является ложным, я проверяю следующие два числа в списке.Не удалось совместить ожидаемый тип «Bool» с фактическим типом '(a, a)'

Код:

positionChecker Pos ns = if compareDistance(ns !! Pos, ns !! (Pos+1)) 
         then Pos 
         else positionChecker(Pos+1) ns 

compareDistance n1 n2 = if abs(n1 - n2) < 0.01 
         then True 
         else False 

(NB: Я удалил код предшествующего, который строит список и вызывает positionChecker, инициализацией его с позицией 0 и список номеров)

Выше возвращая следующую ошибку;

pchk.hs:9:49: 
Couldn't match expected type ‘Bool’ with actual type ‘(a, a)’ 

Relevant bindings include 
    ns :: [a] (bound at pchk.hs:9:21) 
    positionChecker' :: Int -> [a] -> a (bound at pchk.hs:9:1) 
In the first argument of ‘compareDistance’, namely 
    ‘(ns !! Pos, ns !! (Pos + 1))’ 
In the expression: 
    compareDistance (ns !! Pos, ns !! (Pos + 1)) 
In the expression: 
    if compareDistance (ns !! Pos, ns !! (Pos + 1)) then 
     ns !! (Pos + 1) 
    else 
     positionChecker' (Pos + 1) ns 

Опять же, от того, что я могу это сделать, Haskell, кажется, смущает тот факт, что compareDistance возвращается тип Bool.

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

+1

Правило № 1: Всегда добавляйте тип функции. Типы помогут вам и задокументируют ваш код. – Shoe

+1

Почему не 'compareDistance' просто:' compareDistance n1 n2 = abs (n1 - n2) <0.01'? – Shoe

ответ

3

Некоторые комментарии видеть код:

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

positionChecker Pos ns = ...

  • Не используйте !! функцию, это небезопасно:

λ> [0,1] !! 3 *** Exception: Prelude.(!!): index too large

  • Всегда пишите тип подписи для вашего функции. Это поможет вам более легко отладить вашу проблему.

  • Haskell имеет концепцию каррирования. Таким образом, вы не передаете параметры, как это:

compareDistance(ns !! Pos, ns !! (Pos+1))

, но как это:

compareDistance (ns !! Pos) (ns !! (Pos+1)) 
+0

Спасибо!Есть ли достойные статьи, которые вы можете порекомендовать по карри? Плохое прохождение аргумента/размещение парен, похоже, постоянно меня отключает в обучении. – learningHaskell

+1

@learningHaskell Вам следует начать с http://learnyouahaskell.com/ – Sibi

2

Вы вызываете «compareDistance» с кортежем как параметр вместо того, чтобы давать ему два аргумента. Удалите скобки и кому. Это Haskell, а не C.

1

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