2009-12-08 2 views
1

Может ли кто-нибудь помочь в этом экзизе?Haskell IO с цифрами

Напишите программу, которая запрашивает у пользователя для основания и высоты правого прямоугольного треугольника, вычисляет площадь его и выводит его на экран. взаимодействие должно выглядеть как:

The base? 
3.3 
The height? 
5.4 
The area of that triangle is 8.91 

решаемых с:

getTriArea :: IO Float 
getTriArea = do 
putStr "The base? " 
base <- getLine 
putStr "The height? " 
height <- getLine 
let ar = ((read base :: Float) * (read height :: Float))/ 2 
return ar 

main = do 
result <- getTriArea 
putStr $ "The area of that triangle is " ++ show result 
+4

Что вы делали до сих пор? –

+0

То, что Haskell IO с поплавками и номерами уже разрушил мой разум, но у меня есть ответ. Итак, теперь я решил, что он решен –

+0

Затем нажмите галочку рядом с одним из ответов. –

ответ

13

Что у вас есть работа, но это лучше Haskell стиль отделить чистые от IO. Ваш расчет getTriArea не нужно запирать в монаде IO: поднимите его!

import Control.Applicative 

prompt :: (Read a) => String -> IO a 
prompt s = putStr s >> read <$> getLine 

triArea :: (Fractional a) => a -> a -> a 
triArea base height = (base * height)/2 

main :: IO() 
main = do 
    area <- triArea <$> prompt "The base? " <*> prompt "The height? " 
    putStrLn $ "The area of that triangle is " ++ show (area :: Float) 

Аппликативный на самом деле не нужен, он просто предоставляет несколько довольно инфиксных операторов. Монада прекрасно работает.

import Control.Monad 

prompt :: (Read a) => String -> IO a 
prompt s = putStr s >> fmap read getLine 

triArea :: (Fractional a) => a -> a -> a 
triArea base height = (base * height)/2 

main :: IO() 
main = do -- pick one of the following two lines 
    area <- liftM2 triArea (prompt "The base? ") (prompt "The height? ") 
    area <- return triArea `ap` prompt "The base? " `ap` prompt "The height? " 
    putStrLn $ "The area of that triangle is " ++ show (area :: Float) 

В короткой программе, как это, он не действительно дела все, что много, но учтите, что даже тот импорт, то triArea определения может оставаться чистым.

prompt :: (Read a) => String -> IO a 
prompt s = putStr s >> getLine >>= return . read 

triArea :: (Fractional a) => a -> a -> a 
triArea base height = (base * height)/2 

main :: IO() 
main = do 
    base <- prompt "The base? " 
    height <- prompt "The height? " 
    let area = triArea base height 
    putStrLn $ "The area of that triangle is " ++ show (area :: Float) 
1
getTriArea :: IO Float 
getTriArea = do 
putStr "The base? " 
base <- getLine 
putStr "The height? " 
height <- getLine 
let ar = ((read base :: Float) * (read height :: Float))/ 2 
return ar 

main = do 
result <- getTriArea 
putStr $ "The area of that triangle is " ++ show result 
+1

Аннотации типов и парсеры на этих чтениях являются избыточными. Вы можете просто написать 'read base * read height/2'. Функциональное приложение лево-ассоциативное. – Chuck

0

ч)/2 = Ь (ч/2) = (б/2) ч = б ч/2 в математике, все они одинаковы и дают тот же результат. Так лучше писать просто основание * height/2