gpt4 book ai didi

haskell - Haskell 中的 Guard、if-then-else 与 case

转载 作者:行者123 更新时间:2023-12-03 00:20:50 26 4
gpt4 key购买 nike

我有三个函数来查找列表的第 n 个元素:

nthElement :: [a] -> Int -> Maybe a 
nthElement [] a = Nothing
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)

nthElementIf :: [a] -> Int -> Maybe a
nthElementIf [] a = Nothing
nthElementIf (x:xs) a = if a <= 1
then if a <= 0
then Nothing
else Just x -- a == 1
else nthElementIf xs (a-1)

nthElementCases :: [a] -> Int -> Maybe a
nthElementCases [] a = Nothing
nthElementCases (x:xs) a = case a <= 0 of
True -> Nothing
False -> case a == 1 of
True -> Just x
False -> nthElementCases xs (a-1)

在我看来,第一个函数是最好的实现,因为它是最简洁的。但是其他两个实现是否有什么地方可以让它们变得更可取呢?推而广之,您将如何在使用防护、if-then-else 语句和 case 之间进行选择?

最佳答案

从技术角度来看,所有三个版本都是等效的。

话虽这么说,我对样式的经验法则是,如果你能像英语一样阅读它(将 | 读作“when”,| else 读作“otherwise”和 = 为“is”或“be”),你可能做对了。

if..then..else 适用于当您有一个二元条件或需要做出一个决定时。嵌套的 if..then..else 表达式在 Haskell 中非常罕见,几乎应该总是使用防护。

let absOfN =
if n < 0 -- Single binary expression
then -n
else n

如果每个 if..then..else 表达式位于函数的顶层,则可以用守卫替换,这通常应该是首选,因为您可以添加更多情况那么很容易:

abs n
| n < 0 = -n
| otherwise = n

case..of 适用于有多个代码路径,并且每个代码路径都由值的结构,即通过模式匹配。您很少匹配 TrueFalse

case mapping of
Constant v -> const v
Function f -> map f

守卫补充了 case..of 表达式,这意味着如果您需要根据值做出复杂的决策,首先根据输入的结构做出决策,然后然后根据结构中的值做出决策。

handle  ExitSuccess = return ()
handle (ExitFailure code)
| code < 0 = putStrLn . ("internal error " ++) . show . abs $ code
| otherwise = putStrLn . ("user error " ++) . show $ code

顺便说一句。作为样式提示,如果 之后的内容,请始终在 = 之后或 | 之前创建换行符=/| 对于一行来说太长,或者由于某些其他原因使用更多行:

-- NO!
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)

-- Much more compact! Look at those spaces we didn't waste!
nthElement (x:xs) a
| a <= 0 = Nothing
| a == 1 = Just x
| otherwise = nthElement xs (a-1)

关于haskell - Haskell 中的 Guard、if-then-else 与 case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9345589/

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