问题描述
这一直是我一直想知道的问题。如果语句在大多数编程语言中都是主要的(至少是那些我曾经使用过的语言),但是在Haskell中,它似乎很不起眼。我明白,对于复杂的情况,Haskell的模式匹配比一堆ifs更加干净,但有什么区别吗?举个简单的例子, (是的,我知道它可能只是
如果表达式不是,那么就是使用像头部和 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中皱起了眉头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!