Сортировка списка строк нечувствительно

Я пытаюсь отсортировать список строк нечувствительно в Haskell, но я получаю загадочные сообщения об ошибках. Вот мой код:

import Data.Ord
import Data.List
import Data.Char (toUpper)


sortme :: (Ord a) => [a] -> [a]
sortme n = quickSort insensitively n

insensitively :: (Ord a) => a -> a -> Ordering
insensitively string1 string2 = compare (map toUpper string1) (map toUpper string2)


quickSort :: (Ord a) => (a -> a -> Ordering) -> [a] -> [a]
quickSort _ [] = []
quickSort c (x : xs) = (quickSort c less) ++ (x : equal) ++ (quickSort c more)
    where
        less  = filter (\y -> y `c` x == LT) xs
        equal = filter (\y -> y `c` x == EQ) xs
        more  = filter (\y -> y `c` x == GT) xs

quickSort принимает функцию упорядочения и список строк и сортирует строки по функции упорядочения. нечувствительным является функция упорядочения. Вот мое сообщение об ошибке:

/tmp/haskell114913-7-1rjcqe8/Sort.hs:11:54:
    Could not deduce (a ~ [Char])
    from the context (Ord a)
      bound by the type signature for
                 insensitively :: Ord a => a -> a -> Ordering
      at /tmp/haskell114913-7-1rjcqe8/Sort.hs:10:18-49
      `a' is a rigid type variable bound by
          the type signature for insensitively :: Ord a => a -> a -> Ordering
          at /tmp/haskell114913-7-1rjcqe8/Sort.hs:10:18
    In the second argument of `map', namely `string1'
    In the first argument of `compare', namely `(map toUpper string1)'
    In the expression:
      compare (map toUpper string1) (map toUpper string2)

1 ответ

Решение

Ваши определения функций в порядке, проблемы с сигнатурами типов. Если бы вы удалили сигнатуры типа, он скомпилировался бы. Проблема в том, что вы сказали, что insensitively а также sortme сортировать любые Ord a, но вы использовали map toUpperЭто означает, что он может сортировать только строки. Просто сделайте подписи более конкретными:

sortme :: [String] -> [String]
insensitively :: String -> String -> Ordering

Итак, вы рассматривали это сообщение об ошибке как загадочное, поэтому давайте разберем его. Сообщение об ошибке действительно:

Could not deduce (a ~ [Char])
from the context (Ord a)
  bound by the type signature for
             insensitively :: Ord a => a -> a -> Ordering
  Sort.hs:10:18-49
  `a' is a rigid type variable bound by
      the type signature for insensitively :: Ord a => a -> a -> Ordering
      at Sort.hs:10:18
In the second argument of `map', namely `string1'
In the first argument of `compare', namely `(map toUpper string1)'
In the expression:
  compare (map toUpper string1) (map toUpper string2)

С некоторыми шумами из имен файлов удалены. Первая часть, чтобы смотреть на это

Не мог вывести (a ~ [Char]) из контекста (Ord a)

~ Символ означает равенство типов. Компилятор говорит, что вы сказали, что подпись имеет Ord a => a в этом, но определение говорит, что это должно быть [Char]не просто Ord a в

подпись типа для insensitively :: Ord a => a -> a -> Ordering

Это означает, что вы сказали insensitively сравнивает любые два Ord a значения, но определение функции работает только тогда, когда a является [Char], Остальная часть сообщения об ошибке просто говорит вам, где в вашем коде находится ошибка:

Во втором аргументе mapа именно string1

В первом аргументе compareа именно (map toUpper string1)

В выражении: compare (map toUpper string1) (map toUpper string2)

Другие вопросы по тегам