Как ввести одно целое число с консоли

Придумал себе задачу на базовые элементы языка - "перевести температуру из градусов цельсия в фаренгейты", запнулся на этапе ввода целого числа:

-- Ask temperature in Celsius then convert to Fahrenheit

temperatureFahrenheit temperatureCelsius = 32 + temperatureCelsius * 9 / 5

main = do
    putStrLn "What is temperature in Celsius?"
    c <- getLine
    let temperatureCelsius = (read c :: Int)
    result <- temperatureFahrenheit temperatureCelsius
    putStrLn ("It's " ++ result ++ " in Fahrenheit")

Получаю ошибку компиляции (под рукой нет установленного haskell, это вывод с ideone.com):

[1 of 1] Compiling Main             ( prog.hs, prog.o )

prog.hs:8:30: error:
    • Couldn't match type ‘[Char]’ with ‘Int’
      Expected type: Int
        Actual type: String
    • In the expression: c :: Int
      In an equation for ‘temperatureCelsius’:
          temperatureCelsius = c :: Int
      In the expression:
        do putStrLn "What temperature in Celsius?"
           c <- getLine
           let temperatureCelsius = ...
           result <- temperatureFahrenheit temperatureCelsius
           ....
  |
8 |     let temperatureCelsius = c :: Int
  |                              ^

prog.hs:9:15: error:
    • Couldn't match expected type ‘IO [Char]’ with actual type ‘Int’
    • In a stmt of a 'do' block:
        result <- temperatureFahrenheit temperatureCelsius
      In the expression:
        do putStrLn "What temperature in Celsius?"
           c <- getLine
           let temperatureCelsius = ...
           result <- temperatureFahrenheit temperatureCelsius
           ....
      In an equation for ‘main’:
          main
            = do putStrLn "What temperature in Celsius?"
                 c <- getLine
                 let temperatureCelsius = ...
                 ....
  |
9 |     result <- temperatureFahrenheit temperatureCelsius
  |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Что не так? Мне нужно взять строку, получить на выходе Int - так это по крайней мере мне видится в терминах скажем c#.

Что пытался делать:


Ответы (2 шт):

Автор решения: extrn

Ошибки три

  • над temperatureCelsius производится операция деления, она доступна только для дробных типов (представителей класса Fractional), но не для Int. Либо меняйте тип на Double, либо используйте целочисленное деление div или quot, либо явно приводите типы.
  • temperatureFahrenheit temperatureCelsius не IO-действие, здесь нужно использовать let result = ... вместо result <- ...
  • операция ++ конкатенирует строки а не числа со строками. используйте show для получения строкового представления числа.
→ Ссылка
Автор решения: A K

Так, варианты в целых числах (допустим, перевод цельсий -> кельвин).

Через getLine:

-- Ask temperature in Celsius then convert to Kelvin

temperatureKelvin temperatureCelsius = temperatureCelsius + 273

main = do
    putStrLn "What is temperature in Celsius?"
    c <- getLine
    let temperatureCelsius = (read c :: Int)
    let result = temperatureKelvin temperatureCelsius
    putStrLn ("It's " ++ show result ++ " in Kelvin")

Через readLn:

-- Ask temperature in Celsius then convert to Kelvin

temperatureKelvin temperatureCelsius = temperatureCelsius + 273

main = do
    putStrLn "What is temperature in Celsius?"
    c <- readLn
    let result = temperatureKelvin c
    putStrLn ("It's " ++ show result ++ " in Kelvin")

И допустим надо ввести два числа, одно целое, одно рациональное. Скажем, расчёт ИМТ:

-- Ask mass and height, then calculate BMI (body mass index)
-- Result for mass = 77 and height = 1.70 is 26.643598615916957

bmi mass height = mass / (height * height)

main = do  
    putStrLn ("Enter your mass in kilos")
    mass <- readLn
    putStrLn ("Enter your height in meters")
    h <- getLine
    let height = (read h :: Double)
    let result = bmi mass height
    putStrLn ("Your body mass index is " ++ show result)

Спасибо @extrn за указание на ошибки: когда их сразу больше одной -- непросто понять, почему никак к ответу не получается придти.

→ Ссылка