我定义了一个名称 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
我错过了什么?
答案 0 :(得分:3)
where
子句绑定到单个模式匹配,而不是更宽。 绑定多个guard子句,例如:
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子句中的所有定义都可以看到所有绑定值,所以你的第一个等式将很乐意使用你上一个等式中定义的值。