在Haskell中将"Maybe Int"转换为"Int"

8
我正在处理以下代码,并想找到盒子字符串中数字的索引。因此,我使用了findIndex,但它返回Maybe Int值,而我只需要Int值。
如何将Maybe Int转换为Int值?或者有没有办法从Maybe Int中提取Int值。如果Maybe IntNothing,则代码应打印错误消息。
box:: String
box = unlines $ ["0 | 1 | 2",
                 "---------",
                 "3 | 4 | 5",
                 "---------",
                 "6 | 7 | 8"]

moves = do
        putStrLn " Enter the number"
        number <- readLn :: IO Int
        print number
        findpostion number box

findposition number box = findIndex (==number) box
2个回答

18

您可以在do语句中使用模式匹配来轻松完成此操作:

case findposition number box of
  Just n  -> -- do whatever with n
  Nothing -> putStrLn "Invalid number!" -- you can handle the error however you want.
一个好的选择是创建一个单独的IO操作来获取这个数字:
getNumber = do putStrLn "Enter the number:"
               number <- readLn
               case findposition number box of
                 Just n  -> -- Do whatever
                 Nothing -> putStrLn "Please try again." >> getNumber

这样,如果用户输入无效数字,它将重新提问。

此外,按照当前编写的方式,您的代码将无法工作。您应该有一些其他方法将数字存储在box中作为实际数字;现在,它们是字符串。


实际上,意图是查找用户输入的数字,并在以后用任何其他字符(比如“x”)替换它。 - Rog Matthews
1
啊,既然你正在查看一个字符串,那么你应该读取一个 Char 而不是一个 Int。事实上,你可以完全省略 :: IO Int 这一部分。 - Tikhon Jelvis

12

显然,一般情况下这是不可能的: 当搜索没有成功时,没有规范的整数返回值,因此你得到一个没有这样的值的Nothing

如果你并不关心Nothing的情况(例如,因为你总是确保有一个这样的元素),那么你可以使用Data.Maybe中的fromJust函数,你也可以快速实现它:

findposition number = (\(Just i)->i) . findIndex (==number)

不过这并不是一个推荐的做法,因为你必须确保这不会出问题,而使用适当的模式匹配更容易做到这一点。


他提到他想在Nothing上“返回错误消息”。虽然这有点模糊,但我认为他只是想打印出错误信息而不是让程序崩溃。 - Tikhon Jelvis
4
如果在您的工作环境中存在“规范整数”,您可以使用fromMaybe canonicalInt maybeVal,其中canonicalInt :: IntmaybeVal :: Maybe Int。请参阅Data.Maybe文档 - Dan Burton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接