所以这是我的程序。我想自己实现一个最大功能来完成一项任务。问题是,对我来说,打印前面带有“Just”字样的数字似乎很奇怪......我该如何解决这个问题以只打印一个数字?
mymax :: Ord a=>[a]->Maybe a
mymax [] = Nothing
mymax [x] = Just x
mymax (x:y:xs) = if x < y then mymax(y:xs) else mymax(x:xs)
好吧,Show
实例Maybe
放在Just
那里。如果您不想要它,简单的解决方案是不使用show
myPrint :: Show a => Maybe a -> IO ()
myPrint (Just x) = print x
myPrint n = print n
在这里,我们只是Just
将 s 解包,然后再将它们扔到print
.
另一种选择是失去Maybe
. 你可以用类似的东西来做到这一点maybe
maybe (putStrLn "Nothing") print m
printMay = maybe (putStrLn "Nothing") print
这需要一个值m :: Maybe a
,如果它被Just x
扔到. 否则它只是返回。x
print
putStrLn "Nothing"
你在这里有很多选择!以下解决方案正是您所要求的,不多也不少:*
printMaybe :: Show a => Maybe a -> IO ()
printMaybe m = when (isJust m) $
print (fromJust m)
如果它是一个值,这将打印参数可能是Just
值,否则什么也不做。但是,在大多数情况下,这并不是最好的解决方案。任何时候你看到fromJust
你都应该把它当作一个危险信号。在这种情况下,问题是Nothing
根本没有处理该案件。当列表为空时,我们可能想通知用户或至少做一些事情。再说一次,也许我们不这样做,然后这个解决方案就可以了。
另一种情况是,如果您想在值为 时打印一些东西Nothing
,在这种情况下您可以使用该maybe
函数。
printMaybe m = maybe (putStrLn "List was empty!") print m
这将打印“列表为空!” 如果m
包含Nothing
,否则将打印m
。这当然相当于
printMaybe = maybe (putStrLn "List was empty!") print
您也可以手动使用模式匹配来实现这一点,如下所示:
printMaybe m = case m of
Nothing -> putStrLn "List was empty!"
Just x -> print x
这是等效的,但代码略多。同样,您可以明确地做
printMaybe m = case m of
Nothing -> return ()
Just x -> print x
如果您希望该函数在获得值时根本不做任何事情Nothing
,例如我回答中的第一个函数。
* 这可以通过使用函数的应用实例来更简洁地编写,如下所示:
printMaybe = liftA2
when isJust $ print . fromJust
从字面上看,这确实是它所读的。“当论点是Just时,打印你从Just中得到的东西。”
您可以使用该功能。这将转换为例如。但是要小心,如果你调用它会抛出一个错误。fromJust
:: Maybe a -> a
Just 4
4
fromJust Nothing
为避免该错误,请使用fromMaybe
,如果您将值传递给函数,它将返回一个默认值Nothing
。