Как использовать переменную из строки назначения блока do в предложении where? - PullRequest
5 голосов
/ 13 января 2020

У меня есть следующий пример кода:

{-# LANGUAGE ScopedTypeVariables #-}

main = do
  putStrLn "Please input a number a: "
  a :: Int  <- readLn
  print a

  putStrLn "Please input a number b: "
  b :: Int  <- readLn
  print b

  putStrLn ("a+b+b^2:" ++ (show $ a+b+c))
    where c = b^2

По какой-то причине я не могу использовать переменную b в предложении where, я получаю следующую ошибку:

Main3.hs:13:15: error: Variable not in scope: b
   |
13 |     where c = b^2
   |               ^

Есть идеи, как сделать b доступным в предложении where?

1 Ответ

15 голосов
/ 13 января 2020

Используйте let вместо where:

{-# LANGUAGE ScopedTypeVariables #-}

main = do
  putStrLn "Please input a number a: "
  a :: Int  <- readLn
  print a

  putStrLn "Please input a number b: "
  b :: Int  <- readLn
  print b

  let c = b^2
  putStrLn ("a+b+b^2:" ++ (show $ a+b+c))

Причина проблемы заключается в том, что переменные в предложении where находятся в области действия для всех main, но b не входит в сферу применения до b :: Int <- readLn. В общем случае предложения where не могут ссылаться на переменные, связанные внутри блока do (или в любом месте справа от =, в этом отношении: например, f x = y*2 where y = x+1 - это хорошо, но f = \x -> y*2 where y = x+1 - нет) .

...