如何在特定情况下使用高阶结构

Mic*_*ael 1 haskell maybe

我想编写一个函数,它接受两个Maybe Int参数,如果它们都是Just number,则返回它们中的最小值,如果其中一个是 ,则返回“另一个” Nothing。我对我的第一次尝试不满意:

maybeMin :: Maybe Int -> Maybe Int -> Maybe Int
maybeMin Nothing arr = arr
maybeMin ell Nothing = ell
maybeMin ell@(Just l) arr@(Just r) = if l < r then ell else arr
Run Code Online (Sandbox Code Playgroud)

作为优化,我不想在第三种情况下创建新值;即,我不想写

maybeMin ell@(Just l) arr@(Just r) = Just $ if l < r then l else r
Run Code Online (Sandbox Code Playgroud)

上面的代码看起来很笨拙,在我看来,我应该能够利用, orMaybe的实例这一事实。然而,我最好的尝试去高阶并没有做同样的事情:FunctorApplicativeMonad

maybeMin ell arr = ell >>= (\l -> arr >>= (\r -> if l < r then ell else arr))
Run Code Online (Sandbox Code Playgroud)

因为Nothing如果任一操作数是,它将返回Nothing

有没有一种优雅的方式来做我想做的事?

DDu*_*Dub 9

您查看了FunctorApplicativeMonad,但您可能想查看一下Alternative。作为其使用的一个例子,Just 3 <|> Nothingwill yieldJust 3而 not Nothing

对于您的特定用途,如果您想要单线,您可以尝试:

maybeMin l r = min l r <|> l <|> r
Run Code Online (Sandbox Code Playgroud)

只是为了打破下来,我们首先计算min l r,它使用Ord的实例Maybe给最低的lr如果两者都Just值。如果这有效,那么计算就在那里停止,但如果有一个不是Just,那么我们检查是否l是一个Just值。如果是,那么这就是结果,如果不是,我们最终r作为结果返回。

  • 你甚至不需要`min &lt;$&gt; l &lt;*&gt; r`:`Maybe`是`Ord`,所以你可以只做`min lr`。 (3认同)
  • @MichaelrestoreMonicaCellio 事实上,事实并非如此!当任一参数为“Nothing”时,“maybeMin = min”将返回“Nothing”;相反,只有当两个参数都是“Nothing”时,您才想返回“Nothing”。 (2认同)