2017-01-30 14 views
0

Я определил, где определить имя 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 

Что мне не хватает?

+1

«Где» применяется только к определению непосредственно над ним (например, к «planetYearSecs Earth = 100»). Это меня все время укусы. :) – Alec

ответ

3

Предложение where привязывается к одному шаблону соответствия и не шире. Это делает связывают между несколькими сторожевыми пунктами, такими как:

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 могут видеть все связанные значения, поэтому ваше первое уравнение будет с радостью использовать значение, определенное в вашем последнем уравнении.