为什么如果表达式在Haskell中皱起了眉头? [英] Why are if expressions frowned upon in Haskell?

查看:122
本文介绍了为什么如果表达式在Haskell中皱起了眉头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这一直是我一直想知道的问题。如果语句在大多数编程语言中都是主要的(至少是那些我曾经使用过的语言),但是在Haskell中,它似乎很不起眼。我明白,对于复杂的情况,Haskell的模式匹配比一堆ifs更加干净,但有什么区别吗?



举个简单的例子, (是的,我知道它可能只是 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>和 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆