gpt4 book ai didi

haskell - Haskell中的前置条件检查有哪些选项

转载 作者:行者123 更新时间:2023-12-02 02:50:28 24 4
gpt4 key购买 nike

这是一个简单的问题,我认为答案很复杂。

一个非常常见的编程问题是返回某些内容或未通过前置条件检查的函数。在 Java 中,我会使用一些抛出 IllegalArgumentException 的断言函数。在方法的开头是这样的:

{
//method body
Assert.isNotNull(foo);
Assert.hasText(bar)
return magic(foo, bar);
}

我喜欢这个的是,它是每个先决条件的单线。我不喜欢的是抛出异常(因为异常〜goto)。

在 Scala 中,我使用过 Either,这有点笨拙,但比抛出异常要好。

有人给我建议:
putStone stone originalBoard = case attemptedSuicide of 
True -> Nothing
False -> Just boardAfterMove
where {
attemptedSuicide = undefined
boardAfterMove = undefined
}

我不喜欢的是强调真假,它们本身没有任何意义; attemptedSuicide前提条件隐藏在语法之间,因此与 Nothing 和 putStone 的实际实现没有明显关系(boardAfterMove) 不是很清楚的核心逻辑。启动它不会编译,但我确信这不会破坏我的问题的有效性。

在 Haskell 中可以干净地完成前置条件检查的方法是什么?

最佳答案

在 Haskell 中,使用 MaybeEither比 Scala 更圆滑,所以也许你可能会重新考虑这种方法。如果您不介意,我将使用您的第一个示例来说明这一点。

首先,您通常不会测试 null。相反,您只需使用 Maybe 计算您真正感兴趣的属性。处理失败。例如,如果你真正想要的是列表的头部,你可以写这个函数:

-- Or you can just import this function from the `safe` package

headMay :: [a] -> Maybe a
headMay as = case as of
[] -> Nothing
a:_ -> Just a

对于纯粹的验证,例如 hasText , 那么你可以使用 guard ,适用于任何 MonadPlus喜欢 Maybe :
guard :: (MonadPlus m) => Bool -> m ()
guard precondition = if precondition then return () else mzero

当你专精 guardMaybe单子(monad)然后 return变成 Justmzero变成 Nothing :
guard precondition = if precondition then Just () else Nothing

现在,假设我们有以下类型:
foo :: [A]
bar :: SomeForm

hasText :: SomeForm -> Bool

magic :: A -> SomeForm -> B

我们可以处理 foo 的错误。和 bar并安全地提取 magic 的值函数使用 do Maybe 的符号单子(monad):
example :: Maybe B
example = do
a <- headMay foo
guard (hasText bar)
return (magic a bar)

如果您熟悉 Scala, do符号就像 Scala 的理解。上面的代码去糖:
example =
headMay foo >>= \a ->
guard (hasText bar) >>= \_ ->
return (magic a bar)

Maybe单子(monad), (>>=)return有以下定义:
m >>= f = case m of
Nothing -> Nothing
Just a -> f a

return = Just

...所以上面的代码只是简写:
example = case (headMay foo) of
Nothing -> Nothing
Just a -> case (if (hasText bar) then Just () else Nothing) of
Nothing -> Nothing
Just () -> Just (magic a bar)

...您可以将其简化为:
example = case (headMay foo) of
Nothing -> Nothing
Just a -> if (hasText bar) then Just (magic a bar) else Nothing

...如果没有 do,这可能是您手写的内容或 guard .

关于haskell - Haskell中的前置条件检查有哪些选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17880137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com