Haskell 功能:下面使用where子句和不使用where子句有什么区别?

Haskell 功能:下面使用where子句和不使用where子句有什么区别?,haskell,Haskell,我是Haskell的新手,实现了一个计算体重指数的函数(‎体重指数)。但我必须从两个方面来做: -- 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: cal

我是Haskell的新手,实现了一个计算体重指数的函数(‎体重指数)。但我必须从两个方面来做:

-- 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]
——使用where子句计算BMI
:{
calcBmis::(RealFloat a)=>[(a,a)]->[a]
calcBmis xs=[bmi w h |(w,h)[(a,a)]->[a]

calcBmis xs=[bmi w h |(w,h)在第一个版本中
bmi
calcBmis
的本地参数,如果需要,可以(但不)使用参数
xs

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


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

在使用
where
块和进行新的顶级声明之间有两个关键区别

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

  • 定义内可用变量的范围。在
    块中所做的定义可以看到被定义函数的本地变量名。在您的示例中,尽管您没有使用此事实,
    bmi
    可以在
    where
    块版本中看到名称
    xs
    ;新的顶级声明on的作用域中没有
    xs
    。因此,当将
    where
    -块定义提升到顶层时,有时需要向其添加额外的参数,并在调用它们时将局部变量作为参数传入


  • 谢谢你的回答。现在它为我澄清了!谢谢你的回答。现在它为我澄清了!它太好了,我没有更多的问题。XD
    -- 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]