第二个 where name 不在前一个 where 子句的范围内
second where name is not in scope of the previous where clause
我定义了一个定义名称的地方earthSecondsAYear。遗憾的是,它不在前面的 where 子句的范围内。
代码如下:
module SpaceAge (Planet(..), ageOn) where
data Planet = Mercury
| Venus
| Earth
| Mars
| Jupiter
| Saturn
| Uranus
| Neptune
ageOn :: Planet -> Float -> Float
ageOn planet seconds = (seconds / 100) * planetYearSecs planet
where planetYearSecs Mercury = (earthSecondsAYear / 100) * 0.2408
planetYearSecs Venus = 0.6151
planetYearSecs Mars = 1.8808
planetYearSecs Jupiter = 11.8626
planetYearSecs Saturn = 29.4474
planetYearSecs Uranus = 84.0168
planetYearSecs Neptune = 164.7913
planetYearSecs Earth = 100
where earthSecondsAYear = 31557600
错误信息:
:14:34: error:
Variable not in scope: earthSecondsAYear
我错过了什么?
一个 where
子句绑定到单个 pattern-match,并且没有更宽的范围。它确实 绑定多个保护子句,例如 in:
foo :: Int -> Int
foo 0 = 0
foo x | y < 30 = 5
| otherwise = y
where y = x * x
这可能会让您认为它适用于整个函数定义。但是你不能在这里的第一个等式中使用 y
,就像你不能在问题的第一个等式中使用 earthSecondsAYear
一样,因为你只将它绑定到最后一个等式。
但是,解决方法很简单:无需引入新的 where
子句,只需在现有的 where
子句中添加另一个定义即可:
ageOn :: Planet -> Float -> Float
ageOn planet seconds = (seconds / 100) * planetYearSecs planet
where planetYearSecs Mercury = (earthSecondsAYear / 100) * 0.2408
planetYearSecs Venus = 0.6151
planetYearSecs Mars = 1.8808
planetYearSecs Jupiter = 11.8626
planetYearSecs Saturn = 29.4474
planetYearSecs Uranus = 84.0168
planetYearSecs Neptune = 164.7913
planetYearSecs Earth = 100
earthSecondsAYear = 31557600
在 where
子句中定义多个绑定是完全合法的,只需将它们缩进到同一级别即可。当您这样做时,where 子句内的所有定义都可以看到所有绑定值,因此您的第一个等式将愉快地使用上一个等式中定义的值。
我定义了一个定义名称的地方earthSecondsAYear。遗憾的是,它不在前面的 where 子句的范围内。
代码如下:
module SpaceAge (Planet(..), ageOn) where
data Planet = Mercury
| Venus
| Earth
| Mars
| Jupiter
| Saturn
| Uranus
| Neptune
ageOn :: Planet -> Float -> Float
ageOn planet seconds = (seconds / 100) * planetYearSecs planet
where planetYearSecs Mercury = (earthSecondsAYear / 100) * 0.2408
planetYearSecs Venus = 0.6151
planetYearSecs Mars = 1.8808
planetYearSecs Jupiter = 11.8626
planetYearSecs Saturn = 29.4474
planetYearSecs Uranus = 84.0168
planetYearSecs Neptune = 164.7913
planetYearSecs Earth = 100
where earthSecondsAYear = 31557600
错误信息:
:14:34: error:
Variable not in scope: earthSecondsAYear
我错过了什么?
一个 where
子句绑定到单个 pattern-match,并且没有更宽的范围。它确实 绑定多个保护子句,例如 in:
foo :: Int -> Int
foo 0 = 0
foo x | y < 30 = 5
| otherwise = y
where y = x * x
这可能会让您认为它适用于整个函数定义。但是你不能在这里的第一个等式中使用 y
,就像你不能在问题的第一个等式中使用 earthSecondsAYear
一样,因为你只将它绑定到最后一个等式。
但是,解决方法很简单:无需引入新的 where
子句,只需在现有的 where
子句中添加另一个定义即可:
ageOn :: Planet -> Float -> Float
ageOn planet seconds = (seconds / 100) * planetYearSecs planet
where planetYearSecs Mercury = (earthSecondsAYear / 100) * 0.2408
planetYearSecs Venus = 0.6151
planetYearSecs Mars = 1.8808
planetYearSecs Jupiter = 11.8626
planetYearSecs Saturn = 29.4474
planetYearSecs Uranus = 84.0168
planetYearSecs Neptune = 164.7913
planetYearSecs Earth = 100
earthSecondsAYear = 31557600
在 where
子句中定义多个绑定是完全合法的,只需将它们缩进到同一级别即可。当您这样做时,where 子句内的所有定义都可以看到所有绑定值,因此您的第一个等式将愉快地使用上一个等式中定义的值。