LINUX.ORG.RU

Haskell, конструкция case .. of для строк


0

0

-- Всем привет, проконсультируйте пожалуйста, кто может:

--
-- Имеется некий кастомный тип данных
-- по сути дела пара строк
--
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 :]

sf ★★★
()

оно кидает:

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

case.hs:37:24: Warning: Pattern match(es) are overlapped In a case alternative: _ -> ... Ok, modules loaded: Main.

... не так просто

Pi ★★★★★
()

Замените
title -> Just x
на
title1 -> Just title1
Может, яснее будет :]

sf ★★★
()
Ответ на: комментарий от sf

Всем спасибо за ответы.

Если я правильно понял, вариант с case-ом эквивалентен 
следующему коду (верно?):

tlookup3 title [] = Nothing
tlookup3 title (x:xs) = processX x 
                        where processX title = Just x
                              processX _     = tlookup3 title xs


P.S. А Hugs версии от мая 2006-ого никаких варнингов мне не показал.

anonymous
()
Ответ на: комментарий от anonymous

Да, похоже на то. Если развернуть:

tlookup3 title [] = Nothing
tlookup3 title (x:xs) =  Just x -- кушает все оставшиеся случаи
tlookup3 _     (x:xs) =  tlookup3 title xs

//sf

anonymous
()

(setq geek-mode t)

и чего только люди не делают, только бы lisp не использовать :))

(defun tlookup (key list)
  (cond (list (if (string= key (caar list))
                  (car list)
                (tlookup key (cdr list))))
        (t '("Nothing"))))

(defun test ()
  (let ((key "Foo")
        (pair-list '(("Test" "passed") ("Foo" "bar") 
                     ("Hello" "World") ("War" "Peace") 
                     ("Black" "White"))))
    (tlookup key pair-list)))

(test)

(setq geek-mode nil)

Cy6erBr4in ★★★
()
Ответ на: комментарий от anonymous

Да ну? сделай wc -c на аналогичный код на Java... что, жабой тоже не пользуются? может дело не в количестве символов?

Cy6erBr4in ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.