Извлечение x из (Just x) в Maybe

Я уверен, что это очень просто, но я не могу найти ответ. Я вызываю функцию, которая возвращает Maybe x, и хочу увидеть x. Как мне извлечь x из моего Just x ответа?

seeMyVal :: IO ()
seeMyVal = do
   if getVal == Nothing 
   then do
       putStrLn "Nothing to see here"
   else do
       putStrLn getVal -- what do I have to change in this line?

getVal :: (Maybe String)
getVal = Just "Yes, I'm real!"

Это вызывает ошибку:

Couldn't match type ‘Maybe String’ with ‘[Char]’
Expected type: String
  Actual type: Maybe String
In the first argument of ‘putStrLn’, namely ‘getVal’
In a stmt of a 'do' block: putStrLn getVal

person Mark Karavan    schedule 18.11.2015    source источник


Ответы (3)


С этой подписью есть стандартная функция fromJust.

Используйте Hoogle для поиска, подобного этому, это замечательный инструмент.

person fjarri    schedule 18.11.2015
comment
Это очень опасный инструмент для такой задачи, поскольку он приводит к сбою всей программы, если случайно находит Nothing. Такой код, как if isJust ... then fromJust ... else ...., не является идиоматическим в Haskell, и его не следует предлагать, поскольку существуют безопасные альтернативы. - person chi; 18.11.2015
comment
Я не предлагал этот код. Я предложил 1) функцию с желаемой подписью OP; 2) способ поиска функций по подписи в будущем. Я ничего не знаю о том, что OP хочет с этим делать; его совершенно нормально использовать, например. на жестко запрограммированной карте, где вы знаете, что запрошенный вами ключ существует, и если это не так, его следует заполнить. - person fjarri; 18.11.2015
comment
Hoogle - это всегда хорошее предложение, но, как уже было сказано в этом случае, его результат скорее вреден, чем полезен, поэтому это должен быть только комментарий с большой оговоркой. - person leftaroundabout; 19.11.2015
comment
@leftaroundabout: нет, это не должен быть комментарий, потому что он отвечает на вопрос. Если вам это не нравится, не голосуйте / не принимайте. Нет никаких предостережений, поведение, вызывающее ошибки, четко задокументировано. Честно говоря, я не понимаю всей этой ненависти к fromJust, есть много случаев, когда выдача ошибки является приемлемым и логичным поступком. - person fjarri; 19.11.2015
comment
@fjarri: выдача ошибки редко бывает хорошей идеей, за исключением случаев, когда вы уже находитесь в монаде IO (только там можно правильно отловить ошибки) или если вы просто хотите добавить утверждение «идиотского доказательства», которое действительно никогда не должно срабатывать если не вызвано какой-либо ошибкой. Даже в этом случае: для исключений, которые на самом деле не такие уж и исключительные, правильный тип _2 _ / _ 3_ - лучший способ. И утверждения также должны давать некоторую полезную информацию об отладке, что fromJust почти не дает. Неполное сопоставление с шаблоном даст гораздо более полезное сообщение об ошибке. - person leftaroundabout; 19.11.2015
comment
И наконец: использование частичных функций здесь совершенно не нужно! Правильное исчерпывающее сопоставление с образцом, как показал Даниал Вагнер, лучше во всех отношениях. - person leftaroundabout; 19.11.2015

Идиоматический способ - сопоставление с образцом.

seeMyVal = case getVal of
    Nothing  -> putStrLn "Nothing to see here"
    Just val -> putStrLn val

Если хотите, можете исключить putStrLn:

seeMyVal = putStrLn $ case getVal of
    Nothing  -> "Nothing to see here"
    Just val -> val
person Daniel Wagner    schedule 18.11.2015
comment
Разве не было бы более идиоматично, если бы у вас было два экземпляра для разных конструкторов, например seeMyVal Nothing = ... и seeMyVal (Just val) = ...? - person fjarri; 18.11.2015
comment
@fjarri Я думаю, это не более идиоматично, просто другое: это определяет функцию, тогда как это определяет простое старое действие IO (). - person Daniel Wagner; 18.11.2015

Вы также можете использовать fromMaybe, который принимает значение по умолчанию .

fromMaybe "Nothing to see here..." (Just "I'm real!")

person robertjflong    schedule 18.11.2015