Карты Haskell, возвращая монаду

Функция поиска в Данных. Карта и Данные. IntMap в настоящее время возвращают значения перенесенный в, Возможно, с подписью типа

lookup  :: Ord  k => k -> Map  k a -> Maybe  a

Это раньше имело более общий тип

lookup  :: (Monad  m, Ord  k) => k -> Map  k a -> m a

Я понимаю, что первый, вероятно, уменьшает потребность дополнительной спецификации типа, но последний сделал бы ее намного более общей и позволил бы поиску использоваться в пониманиях списка. Там какой-либо путь состоит в том, чтобы подражать этому поведению с более новой версией, или я должен был бы использовать более старую версию библиотеки?

10
задан sabauma 13 June 2010 в 01:44
поделиться

3 ответа

Лифт Дона преобразует элементы Maybe в их общие аналоги Монады , поэтому, возможно, его следует назвать convert или generalize или что-то в этом роде; -)

Если вы просто хотите использовать lookup , в основном, в понимании списков и других монадах, которые реализуют fail , вы также можете использовать сопоставление сбоя сопоставления с шаблоном с fail :

Prelude> [ v | Just v <- return $ lookup "hi" [("ho","silver")] ]
[]
Prelude> [ v | Just v <- return $ lookup "ho" [("ho","silver")] ]
["silver"]

Prelude> do Just v <- return $ lookup "hi" [("ho","silver")] ; print v
*** Exception: user error (Pattern match failure in do expression at <interactive>:1:3-8)
Prelude> do Just v <- return $ lookup "ho" [("ho","silver")] ; print v
"silver"
5
ответ дан 3 December 2019 в 15:34
поделиться

последний сделает его более общим и позволит искать использоваться в понимании списков

Последнее также более небезопасно, поскольку большинство классов монад определяют отказ как ошибку . То есть обычный случай, когда элемент не обнаруживается на карте, для большинства монад приводит к ошибке завершения программы. Это, в сочетании с повышенной вероятностью вывода неверного контекста типа, означает, что сейчас мы склонны отказываться от стиля «монадического возврата после сбоя».

Есть ли способ имитировать это поведение в новой версии

Действительно есть! Просто переместите Maybe a в Monad a, например:

lift :: Monad m => Maybe a -> m a
lift Nothing  = fail "you die now"
lift (Just a) = return a

И теперь вы можете написать, например лифт. поиск

19
ответ дан 3 December 2019 в 15:34
поделиться

Для конкретного случая монады списка самым простым решением является использование maybeToList:

Prelude> :m +Data.Maybe -- Note: Use "import Data.Maybe" in a program file

Data.Maybe> [ v | v <- maybeToList $ lookup "hi" [("ho","silver")] ]
[]
Data.Maybe> [ v | v <- maybeToList $ lookup "ho" [("ho","silver")] ]
["silver"]
4
ответ дан 3 December 2019 в 15:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: