5

所以这是我的程序。我想自己实现一个最大功能来完成一项任务。问题是,对我来说,打印前面带有“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)
4

3 回答 3

10

好吧,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扔到. 否则它只是返回。xprintputStrLn "Nothing"

于 2013-09-18T04:55:09.393 回答
3

你在这里有很多选择!以下解决方案正是您所要求的,不多也不少:*

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中得到的东西。”

于 2013-09-18T07:55:55.860 回答
2

您可以使用该功能。这将转换为例如。但是要小心,如果你调用它会抛出一个错误。fromJust:: Maybe a -> aJust 44fromJust Nothing

为避免该错误,请使用fromMaybe,如果您将值传递给函数,它将返回一个默认值Nothing

于 2013-09-18T04:55:35.757 回答