【问题标题】:Haskell Maybe type -> typeHaskell 也许类型 -> 类型
【发布时间】:2016-01-05 22:21:10
【问题描述】:

我遇到了这个问题:

Couldn't match expected type ‘Int’ with actual type ‘Maybe Int’

我能以某种方式将“Maybe Int”转换为“Int”吗?

if index == Nothing 
   then 
     do 
       let index = 0
       putStrLn(fancyPrint2 $ kaasasOlevList !! index)
   else 
     do 
       let index = index
       putStrLn(fancyPrint2 $ kaasasOlevList !! index)

我试过这样,但这给了我:

Exception: <<loop>>

【问题讨论】:

    标签: haskell maybe


    【解决方案1】:

    你有几个不同的选择来解决这个问题

    首先使用您的if 语句,但稍作修改(但请避免这样做)

    if index == Nothing 
       then 
         do 
           let index' = 0
           putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
       else 
         do 
           let (Just index') = index
           putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
    

    我在这里写index',因为 Haskell 不允许您覆盖现有变量,但它允许您隐藏它们。但通常最好在最后用“主要”符号 (') 标记变量的“修改”版本。这样您就可以在需要时随时访问原件。

    其次,您可以使用 case 表达式将您的代码转换为

    case index of
      Just i  -> putStrLn $ fancyPrint2 $ kaasasOlevList !! i
      Nothing -> putStrLn $ fancyPrint2 $ kaasasOlevList !! 0
    

    或者,如果您使用where 子句稍微清理一下:

    case index of
      Just i  -> putIndex i
      Nothing -> putIndex 0
    where putIndex x = putStrLn $ fancyPrint2 $ kaasasOlevList !! x
    

    最后有 fromMaybe 可以让你这样做:

    import Data.Maybe (fromMaybe)
    
    -- ...
    
    do
      let index' = fromMaybe 0 index
      putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
    

    你也可以使用守卫。但是看到我不知道你的 code-sn-p 来自哪里,我不知道使用警卫是否合理。

    您可以阅读更多关于守卫、案例表达式和模式匹配的信息here

    【讨论】:

    • 我建议不要使用if,除非非常必要。并不是说您在 monadic 环境中执行此操作,这意味着您强制执行计算顺序,这违反了 Haskell 的惰性编程原则。
    • @WillemVanOnsem 哦,我完全同意。我只是想展示几种不同的方法来做到这一点
    【解决方案2】:

    是的,你可以使用fromMaybe函数:

    fromMaybe :: a -> Maybe a -> a
    

    它的工作原理如下,第一个参数是默认值,如果第二个是Nothing,则使用它,接下来是Maybe a,如果该值是Just x,返回x。所以fromMaybe 的实现可能是:

    fromMaybe _ (Just x) = x
    fromMaybe d Nothing = d
    

    所以你可以使用:

    import Data.Maybe(fromMaybe)
    
    --...
    
    putStrLn(fancyPrint2 $ kaasasOlevList !! (fromMaybe 0 index))
    

    没有所有if-then-else 至极un-Haskell


    为什么会循环?如果你的indexJust x 的形式,它会进入以下分支:

    do 
       let index = index
       putStrLn(fancyPrint2 $ kaasasOlevList !! index)
    

    现在的表达式:

       let index = index
    

    表示您将index 分配给它自己(而不是外部的index)。这在函数式编程语言中并不是真正的问题,尽管如果您想使用这样的函数就会出现问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多