我遇到了这个问题:
Couldn't match expected type ‘Int’ with actual type ‘Maybe Int’
Run Code Online (Sandbox Code Playgroud)
我可以以某种方式将'Maybe Int'转换为'Int'吗?
if index == Nothing
then
do
let index = 0
putStrLn(fancyPrint2 $ kaasasOlevList !! index)
else
do
let index = index
putStrLn(fancyPrint2 $ kaasasOlevList !! index)
Run Code Online (Sandbox Code Playgroud)
我试过这样,但这给了我:
Exception: <<loop>>
Run Code Online (Sandbox Code Playgroud)
是的,你可以使用这个fromMaybe功能:
fromMaybe :: a -> Maybe a -> a
Run Code Online (Sandbox Code Playgroud)
其工作原理如下,第一个参数是默认值,你的情况下,第二个是使用的东西Nothing,旁边跟随Maybe a,如果该值Just x,x则返回.所以实现fromMaybe可能是:
fromMaybe _ (Just x) = x
fromMaybe d Nothing = d
Run Code Online (Sandbox Code Playgroud)
所以你可以使用:
import Data.Maybe(fromMaybe)
--...
putStrLn(fancyPrint2 $ kaasasOlevList !! (fromMaybe 0 index))
Run Code Online (Sandbox Code Playgroud)
没有所有这些if-then-else都是非Haskell.
它为什么循环?好吧,如果你index的形式Just x,它进入以下分支:
do
let index = index
putStrLn(fancyPrint2 $ kaasasOlevList !! index)
Run Code Online (Sandbox Code Playgroud)
现在表达式:
let index = index
Run Code Online (Sandbox Code Playgroud)
意味着你分配index 给自己(而不是外部index).这在函数式编程语言中并不是一个问题,尽管如果你想使用这样的函数会出现问题.
你有几种不同的选择来解决这个问题
首先是使用你的if声明,但稍作修改(尽管避免这样做)
if index == Nothing
then
do
let index' = 0
putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
else
do
let (Just index') = index
putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
Run Code Online (Sandbox Code Playgroud)
我在index'这里写,因为Haskell不允许你覆盖现有的变量,但它确实让你隐藏它们.但一般来说,更好的做法是'在末尾用"prime"符号()标记变量的"修改"版本.这样,如果需要,您可以随时访问原始文件.
其次,您可以使用case将代码转换为的表达式
case index of
Just i -> putStrLn $ fancyPrint2 $ kaasasOlevList !! i
Nothing -> putStrLn $ fancyPrint2 $ kaasasOlevList !! 0
Run Code Online (Sandbox Code Playgroud)
或者如果你使用一个where子句清理一下:
case index of
Just i -> putIndex i
Nothing -> putIndex 0
where putIndex x = putStrLn $ fancyPrint2 $ kaasasOlevList !! x
Run Code Online (Sandbox Code Playgroud)
最后,fromMaybe这可以让你这样做:
import Data.Maybe (fromMaybe)
-- ...
do
let index' = fromMaybe 0 index
putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
Run Code Online (Sandbox Code Playgroud)
你也可以使用警卫.但由于我不知道你的代码片段来自何处,我不知道使用警卫是否合理.
| 归档时间: |
|
| 查看次数: |
420 次 |
| 最近记录: |