为什么如果表达式在Haskell中皱起了眉头? [英] Why are if expressions frowned upon in Haskell?
问题描述
举个简单的例子, (是的,我知道它可能只是 foldr(+)0
):
sum :: [Int] - > Int
- 将所有情况分开
sum [] = 0
sum(x:xs)= x + sum xs
- guard
总和xs
| null xs = 0
|否则=(head xs)+ sum(tail xs)
- case
sum xs = case xs of
[] - > 0
_ - > (head xs)+ sum(tail xs)
- if语句
sum xs = if null xs then 0 else(head xs)+ sum(tail xs)
作为第二个问题,这些选项中的哪一个被认为是最佳实践,为什么?我的教授总是尽可能使用第一种方法,我想知道这是否只是他个人的偏好,或者是否有背后的原因。
解析方案如果表达式不是,那么就是使用像
头部
和 tail
。如果您尝试用空列表调用其中之一,则会抛出异常。
> head []
***例外:Prelude.head:空列表
>尾巴[]
***例外:Prelude.tail:空目录
使用这些函数编写代码时出现错误,直到运行时才会检测到错误。例如,假设您意外地切换了,然后$ c> $ c>和
else
函数的一部分。
- 编译,在运行时抛出错误。
sum xs = if null xs then(head xs)+ sum(tail xs)else 0
- 不编译。视觉上也更加突出。
sum [] = x + sum xs
sum(x:xs)= 0
请注意,您的守卫示例具有相同的问题。
This has been a question I've been wondering for a while. if statements are staples in most programming languages (at least then ones I've worked with), but in Haskell it seems like it is quite frowned upon. I understand that for complex situations, Haskell's pattern matching is much cleaner than a bunch of ifs, but is there any real difference?
For a simple example, take a homemade version of sum (yes, I know it could just be foldr (+) 0
):
sum :: [Int] -> Int
-- separate all the cases out
sum [] = 0
sum (x:xs) = x + sum xs
-- guards
sum xs
| null xs = 0
| otherwise = (head xs) + sum (tail xs)
-- case
sum xs = case xs of
[] -> 0
_ -> (head xs) + sum (tail xs)
-- if statement
sum xs = if null xs then 0 else (head xs) + sum (tail xs)
As a second question, which one of these options is considered "best practice" and why? My professor way back when always used the first method whenever possible, and I'm wondering if that's just his personal preference or if there was something behind it.
The problem with your examples is not the if
expressions, it's the use of partial functions like head
and tail
. If you try to call either of these with an empty list, it throws an exception.
> head []
*** Exception: Prelude.head: empty list
> tail []
*** Exception: Prelude.tail: empty list
If you make a mistake when writing code using these functions, the error will not be detected until run time. If you make a mistake with pattern matching, your program will not compile.
For example, let's say you accidentally switched the then
and else
parts of your function.
-- Compiles, throws error at run time.
sum xs = if null xs then (head xs) + sum (tail xs) else 0
-- Doesn't compile. Also stands out more visually.
sum [] = x + sum xs
sum (x:xs) = 0
Note that your example with guards has the same problem.
这篇关于为什么如果表达式在Haskell中皱起了眉头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!