2015-05-24 3 views
1

Я реализует алгоритм kadane в Haskell, AFAIK она работает правильноПочему я не могу удалить Ord Typeclass из этой реализации haskell алгоритма Кадана?

kadane' :: (Ord a, Num a) => [a] -> a 
kadane' xs = head$ foldl maxsub [0,0] xs 

maxsub :: (Ord a, Num a) => [a] -> a -> [a] 
maxsub x y 
    | last(x)+y > head(x) = if last(x)+y > 0 then [last(x)+y, last(x)+y] else [last(x)+y, 0] 
    | otherwise = if last(x)+y > 0 then [head(x), last(x)+y] else [head(x), 0] 

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

*Main> :t kadane' 
kadane' :: (Ord a, Num a) => [a] -> a 
*Main> :t maxsub 
maxsub :: (Ord a, Num a) => [a] -> a -> [a] 
*Main> 

Если удалить Ord класс типов, как показано ниже

kadane' :: (Num a) => [a] -> a 
kadane' xs = head$ foldl maxsub [0,0] xs 

maxsub :: (Num a) => [a] -> a -> [a] 
maxsub x y 
    | last(x)+y > head(x) = if last(x)+y > 0 then [last(x)+y, last(x)+y] else [last(x)+y, 0] 
    | otherwise = if last(x)+y > 0 then [head(x), last(x)+y] else [head(x), 0] 

и компиляции выше код бросает следующую ошибку

*Main> :l kadanes.hs 
[1 of 1] Compiling Main    (kadanes.hs, interpreted) 

kadanes.hs:6:21: 
    Could not deduce (Ord a) arising from a use of ‘>’ 
    from the context (Num a) 
     bound by the type signature for maxsub :: Num a => [a] -> a -> [a] 
     at kadanes.hs:4:11-36 
    Possible fix: 
     add (Ord a) to the context of 
     the type signature for maxsub :: Num a => [a] -> a -> [a] 
    In the expression: last (x) + y > head (x) 
    In a stmt of a pattern guard for 
        an equation for ‘maxsub’: 
     last (x) + y > head (x) 
    In an equation for ‘maxsub’: 
     maxsub x y 
      | last (x) + y > head (x) 
      = if last (x) + y > 0 then 
       [last (x) + y, last (x) + y] 
      else 
       [last (x) + y, 0] 
      | otherwise 
      = if last (x) + y > 0 then 
       [head (x), last (x) + y] 
      else 
       [head (x), 0] 
Failed, modules loaded: none. 
Prelude> 

В соответствии с возможным исправлением, сообщенным в ошибке, мне нужно снова добавить Ord typeclass, что я делаю неправильно?

А также, пожалуйста, оценить правильность алгоритма, если это возможно предложить альтернативные способы

+0

Стиль comment: функция 'maxsub' должна принимать' (a, a) 'вместо' [a] ', так как вы знаете, что будет ровно два аргумента. Это также позволит вам избежать опасных частичных функций, таких как 'head, last', и просто использовать сопоставление с образцом, чтобы извлечь их, например. 'maxsub (x1, x2) y = ...' – chi

ответ

3

Вы не можете удалять Ord, так как вы используете такие функции, как < и > и их эксплуатации на полиморфного типа. Смотрите их тип:

λ> :t (<) 
(<) :: Ord a => a -> a -> Bool 

Но если вы вместо того, чтобы ограничить свой полиморфный код для работы только на Int или любой другой мономорфной например, для которых Ord экземпляр уже определен, то вы можете удалить его:

maxsub :: [Int] -> Int -> [Int] 
maxsub x y 
    | last(x)+y > head(x) = if last(x)+y > 0 then [last(x)+y, last(x)+y] else [last(x)+y, 0] 
    | otherwise = if last(x)+y > 0 then [head(x), last(x)+y] else [head(x), 0] 

kadane' :: [Int] -> Int 
kadane' xs = head$ foldl maxsub [0,0] xs 
Смежные вопросы