函数:使用和不使用where子句之间的区别是什么?

时间:2018-10-29 18:48:14

标签: haskell

我是Haskell的新手,并实现了计算BMI(身体质量指数)的功能。但是我必须通过两种方式做到这一点:

Year District                                                   
2017 Albany                      223057.0            416302.0   
    Albany                           NaN                 NaN   
    Allegany                     36935.0             69802.0   
    Allegany                         NaN                 NaN   
    Broome                      201586.0            363504.0   
    Broome                           NaN                 NaN   
    Cattaraugus                  75567.0            144572.0   
    Cattaraugus                      NaN                 NaN     

-- Calculate BMI using where clause
:{
calcBmis :: (RealFloat a) => [(a, a)] -> [a]  
calcBmis xs = [bmi w h | (w, h) <- xs]  
    where bmi weight height = weight / height ^ 2
:}
-- Input: calcBmis [(70, 1.7), (90, 1.89)]
-- Output: [24.221453287197235, 25.195263290501387]

两者都能完美工作!唯一的区别是第一个使用-- Calculate BMI using just list comprehension :{ calcBmis :: (RealFloat a) => [(a, a)] -> [a] calcBmis xs = [bmi w h | (w, h) <- xs] bmi weight height = weight / height ^ 2 :} -- Input: calcBmis [(70, 1.7), (90, 1.89)] -- Output: [24.221453287197235, 25.195263290501387] 。如果必须声明常量或多个函数,我已经知道哪种where是好的。我不知道是否存在另一种使用它的方式,但是直到现在我仍然学到了这样的东西。

我想知道这两个函数之间的区别是否只是干净的代码,或者在这种情况下它背后还有其他特殊之处?

2 个答案:

答案 0 :(得分:6)

使用this.test= function () { let searchingDate = "2017-05%"; return model.table.findAll({ where: { dateAttribute: searchingDate } }) } 块和进行新的顶层声明之间有两个主要区别。

  1. 新定义的变量的作用域。 where块的作用域比顶级声明更有限:在您的示例中,使用where块,我无法从where的实现外部调用bmi ,但可以使用其他顶级声明。

  2. 定义中可用变量的作用域。在calcBmis块中进行的定义可以看到正在定义的函数本地的变量名。在您的示例中,尽管您没有使用此事实,但是where可以在bmi块版本中看到名称xs;新的顶层声明的范围内没有where。因此,在将xs块定义提升到顶层时,有时有必要向它们添加额外的参数,并在调用它们时将局部变量作为参数传递。

答案 1 :(得分:1)

在第一个版本中,bmicalcBmis的本地版本,如果愿意,可以(但不)使用参数xs

在第二个版本中,bmi是一个全局函数,就像calcBmis一样,因此您可以从任何地方调用它。

因此,如果在输入第一个代码后在GHCi中输入bmi 1 2,则会收到关于未定义bmi的错误,但在第二个代码之后,它将正常工作。