2009-12-08 7 views
1

Quelqu'un peut-il aider avec cet exercice?Haskell IO avec numéros

Ecrire un programme qui demande à l'utilisateur pour la base et la hauteur d'un triangle rectangle droite, calcule sa zone et il imprime à l'écran. L'interaction devrait ressembler à quelque chose comme :

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

Résolu avec:

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

Qu'avez-vous essayé jusqu'à présent? –

+0

Que Haskell IO avec des flotteurs et des numéros ont déjà détruit mon esprit, mais j'ai une réponse. Donc, je suppose que c'est maintenant résolu –

+0

Puis cliquez sur la coche à côté de l'une des réponses. –

Répondre

13

Qu'est-ce que vous avez des œuvres, mais il vaut mieux le style Haskell pour séparer pur de IO. Votre calcul getTriArea n'a pas besoin d'être verrouillé dans la monade IO: retirez-le!

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) 

Applicatif n'est pas réellement nécessaire, il fournit juste quelques opérateurs assez infixes. Monad fonctionne très bien.

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) 

Dans un programme court comme celui-ci, il ne vraiment question tout ce que beaucoup, mais notez que même les importations, la définition triArea peuvent rester pure.

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

Les annotations de type et les parenthèses sur ces lectures sont redondantes. Vous pouvez simplement écrire 'read base * read height/2'. L'application de la fonction est associative à gauche. – Chuck

0

(b h)/2 = b (h/2) = (b/2) h = b h/2 de mathématiques, ils sont tous les mêmes et donner le même résultat. Mieux vaut écrire simplement base * height/2