Haskell 也许输入 -> 输入
Haskell Maybe type -> type
我 运行 遇到这个问题 :
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>>
是的,你可以使用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
)。这在函数式编程语言中并不是真正的问题,尽管如果您希望使用这样的函数。
就会出现问题
您有几种不同的选择来解决这个问题
首先是使用您的 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 不允许您覆盖现有变量,但是它允许您隐藏它们。但一般来说,更好的做法是在变量的 "modified" 版本末尾使用 "prime" 符号 ('
) 进行标记。这样您就可以在需要时随时访问原件。
其次,您可以使用 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-snippet 来自哪里,我不知道使用守卫是否合理。
您可以阅读更多关于守卫、case 表达式和模式匹配的内容here
我 运行 遇到这个问题 :
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>>
是的,你可以使用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
)。这在函数式编程语言中并不是真正的问题,尽管如果您希望使用这样的函数。
您有几种不同的选择来解决这个问题
首先是使用您的 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 不允许您覆盖现有变量,但是它允许您隐藏它们。但一般来说,更好的做法是在变量的 "modified" 版本末尾使用 "prime" 符号 ('
) 进行标记。这样您就可以在需要时随时访问原件。
其次,您可以使用 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-snippet 来自哪里,我不知道使用守卫是否合理。
您可以阅读更多关于守卫、case 表达式和模式匹配的内容here