-- Всем привет, проконсультируйте пожалуйста, кто может:
--
-- Имеется некий кастомный тип данных
-- по сути дела пара строк
--
data SPair = SPair String String deriving (Eq, Show)
--
-- некоторый тестовый набор данных
--
testList = [SPair "test1" "abc", SPair "hello" "world",
SPair "goodby" "hell"]
--
-- обьявлена функция получения первой строки пары
--
first (SPair x _) = x
--
-- и имеется 2 реализации функции поиска пары в списке, по
-- значению первой строки как по ключу:
--
--
-- Вариант 1 использует охранные инструкици для организации
-- ветвления:
--
tlookup1 title [] = Nothing
tlookup1 title (x:xs) | (first x) == title = Just x
| otherwise = tlookup1 title xs
--
-- Вариант 2 использует для тех-же целей case .. of :
--
tlookup2 title [] = Nothing
tlookup2 title (x:xs) = case (first x) of
title -> Just x
_ -> tlookup2 title xs
--
-- Ну и закладки для запуска
--
test1 = tlookup1 "hello" testList
test2 = tlookup2 "hello" testList
--
-- Имеем на выходе: вариант 1 корректно работает, а вариант 2
-- возвращает всегда первый элемент списка, как будто-бы
-- под первый кейс подходят любые заголовки.
-- Подскажите куда смотреть
--
Охрана использует предикат (:: Bool), а case - сопоставление с шаблонами.
Не зря GHC говорит:
Warning: Pattern match(es) are overlapped
In a case alternative: _ -> ...
Можно case заменить на что-то вроде case (compare title (first x)) of
EQ ->
_ ->
но похоже это эмуляция if :]
Всем спасибо за ответы.
Если я правильно понял, вариант с case-ом эквивалентен
следующему коду (верно?):
tlookup3 title [] = Nothing
tlookup3 title (x:xs) = processX x
where processX title = Just x
processX _ = tlookup3 title xs
P.S. А Hugs версии от мая 2006-ого никаких варнингов мне не показал.
Да, похоже на то. Если развернуть:
tlookup3 title [] = Nothing
tlookup3 title (x:xs) = Just x -- кушает все оставшиеся случаи
tlookup3 _ (x:xs) = tlookup3 title xs
//sf