我遇到了这个问题:
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>>
答案 0 :(得分:5)
是的,您可以使用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 。
为什么会循环播放?如果您的index
格式为Just x
,则会进入以下分支:
do
let index = index
putStrLn(fancyPrint2 $ kaasasOlevList !! index)
现在表达式:
let index = index
表示您将index
分配给自己(而非外部index
)。这在功能性编程语言中并不是真正的问题,但如果你想要使用这样的功能会出现问题。
答案 1 :(得分:5)
您有几种不同的选择来解决这个问题
首先使用你的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'
你也可以使用警卫。但由于我不知道你的代码片段来自何处,我不知道使用警卫是否合理。
您可以阅读有关警卫,案例表达和模式匹配的更多信息here