2013-05-14 3 views
1

Я новичок в Haskell и имеют проблемы в следующем блоке:Неприятности с условием Haskell

up_heap :: Num a => [a] -> [a] -> [a] 
up_heap heap (h:t) = 
let ppos = quot (length heap) 2 in 
     case ((ppos > 0) && ((heap !! ppos) > h)) of 
      True -> 
       let (upper, (p:lower)) = splitAt ppos heap in 
        up_heap upper (h:lower) ++ (p:t) 
      False -> 
       heap ++ h:t 

Следующая ошибка: Не удалось вывести (Ord а), возникающие в связи с использованием `>»

Как улучшить это?

ответ

6

Вы используете > на элементе heap, который имеет тип Num a => a (элемент). > является частью класса Ord и, как вы могли видеть в документации (http://hackage.haskell.org/packages/archive/base/3.0.3.1/doc/html/GHC-Num.html), реализация типа Num не обязательно реализует Ord.

class (Eq a, Show a) => Num a where 

Добавить ограничение в ваш тип подписи, как (Num a, Ord a) => ....

+0

Но я имею в виду, что куча - это список и возврат кучи !! ppos - это число. Я пытаюсь переписать это с помощью двух операндов functioun: up_heap :: Num a => ([ a], [a]) -> [a] – vporoshok

+0

Хорошо! Орд вместо Num. Спасибо! – vporoshok

1

Я тоже начинаю. Я делал немного диаграммы, как я иду вдоль, которая может оказаться полезной для вас:

Eq -- specifies the functions: (==) (/=) 
     Also, a required typeclass for a variable if: 
      1) you check to see if a variable is in a list with the `elem` list function 
      2) a variable is being pattern matched against a specific value 
      3) you pass a variable to another function that requires its arg to be (Eq a) 

Ord -- specifies the functions: (<) (<=) (>) (>=) 
      (Ord implements Eq) 

Num -- specifies the functions: (+) (-) (*) 
      but NOT (/) which is part of the Fractional typeclass 
      (Num implements Show, Eq) 

      ghci> :t (*) 
      (*) :: (Num a) => a -> a -> a 

Integral -- specifies the functions: mod, div(integer division operator)     
       Both Int and Integer(= really big ints) implement the 
       Integral typeclass 
       (Integral implements Real(which implements both Ord and Num)) 

Fractional -- specifies the function: (/) 
       Float, Double, Rational types implement Fractional 
       (Fractional implements Num) 

Когда я первый пишу заявление типа, я не слишком беспокоиться о «ограничениях типа» я мог бы нужно, так что я мог бы написать:

myfunc :: a -> a -> a 

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

myfunc :: (Num a, Ord a) => a -> a -> a 

типа «а» обозначает любого типа и ограничения типа, (Num а, Ord а), скажем, «Держись там, ни один тип не будет делать для« а ». Будет сделано некоторое добавление и сравнение с этими а, поэтому тип« а »ограничен от любого типа до тип, который реализует функции в Num и Ord.

+0

«Во-первых, я не слишком беспокоюсь о« ограничениях типа », которые мне могут понадобиться» Это возможно; однако IMO лучше разрабатывать свои функции подписи - сначала («для каких типов мне это нужно работать?»), а не для реализации в первую очередь («это легко, если я могу использовать эту операцию ... ... darn, now Я застрял с глупым ограничением MagicalSelfmanager, и я просто хочу, чтобы функция работала на 'Int's! '). Кроме того, подписи часто дают вам хорошее руководство по написанию функции. – leftaroundabout

+0

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

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