【问题标题】:Extracting x from (Just x) in a Maybe [duplicate]在 Maybe [重复] 中从 (Just x) 中提取 x
【发布时间】:2015-11-18 06:25:45
【问题描述】:

我敢肯定,超级简单,但我似乎找不到答案。我调用了一个返回Maybe x 的函数,我想查看x。如何从我的Just x 回复中提取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

【问题讨论】:

    标签: haskell types maybe


    【解决方案1】:

    惯用的方式是模式匹配。

    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
    

    【讨论】:

    • 如果您有两个不同构造函数的实例,例如seeMyVal Nothing = ...seeMyVal (Just val) = ...,这不是更习惯吗?
    • @fjarri 不是更惯用的,我认为,只是不同:这将定义一个函数,而这定义一个普通的旧 IO () 动作。
    【解决方案2】:

    您也可以使用fromMaybe,它采用默认值。

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

    【讨论】:

      【解决方案3】:

      这个签名有一个标准函数fromJust

      使用 Hoogle 进行类似这样的搜索,it's a wonderful tool

      【讨论】:

      • 对于这样的任务,这是一个非常危险的工具,因为如果它碰巧找到Nothing,它会使整个程序崩溃。 if isJust ... then fromJust ... else .... 之类的代码在 Haskell 中不是惯用的,不建议使用,因为确实存在安全的替代方案。
      • 我没有建议这个代码。我的建议是 1)一个带有 OP 想要的签名的函数; 2)将来通过签名查找功能的方法。我不知道 OP 想用它做什么。使用它非常好,例如在您知道所请求的密钥存在的硬编码地图上,如果不存在,则应填写。
      • Hoogle 总是一个很好的建议,但正如在这种情况下已经说过的那样,它的结果弊大于利,所以它应该只是一个带有很大警告的评论。
      • @fjarri:抛出错误很少是一个好主意,除非你已经在 IO monad 中(只有错误才能被正确捕获),或者你只想添加一个“白痴证明”断言真的不应该触发,除非由一些错误触发。即便如此:对于并非真正异常的异常,正确的 Either/ErrorT 类型是可行的方法。断言还应该提供一些有用的调试信息,fromJust 几乎没有。非详尽的模式匹配将提供更有用的错误消息。
      • 最后:这里完全不需要使用偏函数!正如 Danial Wagner 所展示的那样,适当的详尽模式匹配在各个方面都更好
      猜你喜欢
      • 2016-07-24
      • 2022-01-12
      • 2016-08-29
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多