2009-11-26 7 views
3

a) Je dois lancer de String à int en haskell. J'ai une fonction qui obtient le troisième mot dans une phrase comme une chaîne, mais mon troisième mot dans toutes mes phrases sont des nombres (int), comment puis-je lancer de chaîne à int alors je peux utiliser le numéro après pour faire des opérations comme ajouter ou mult?Casting dans Haskell

getThirdWord :: String -> String 
getThirdWord = head . tail . tail . words 

b) J'utilise Visual Haskell Studio. Comment puis-je utiliser des fonctions comme map et zip dans visual haskell studio? Y a-t-il des plugins que je dois inclure dans mes vhs pour les faire fonctionner?

Merci beaucoup d'avance!

Répondre

6

En ce qui concerne la coulée, jetez un oeil à la fonction read.

getThirdWord :: String -> Int 
getThirdWord = read . head . tail . tail . words 

Visual Haskell Studio semble y avoir une seule IDE, en ce que l'arrière-plan utilise GHC, qui supporte entièrement la spécification Haskell et comprend les bibliothèques qui comprennent Plan et pli.

+0

Je pense que vous voulez 'read .' au lieu de' read $ '. –

14

Yacoby's answer est correct bien sûr. Permettez-moi de faire deux remarques:

  1. read est très général. Il convertit non seulement String en Int. Son type de retour dépend du contexte. Dans ce cas getThirdWord est défini comme String -> Int, donc read sait quoi faire. Ce n'est pas toujours le cas, donc si jamais vous obtenez une erreur de compilation en utilisant read, rappelez-vous ceci: vous devrez peut-être aider Haskell à déterminer le type de retour.
  2. Actuellement, vous utilisez head . tail . tail pour obtenir le troisième élément de la liste. Et si vous vouliez, disons, le 23ème élément? Une solution plus maintenable et lisible est d'utiliser (!!): de cette façon, vous pouvez récupérer un élément de la liste à n'importe quel index. Ainsi:

    thirdWordAsInt :: String -> Int 
    thirdWordAsInt = read . (!! 2) . words 
    

    (. Notez le 2 au lieu d'un 3, puisque les indices sont 0-indexés)

3

Je deuxième Yacoby d'utiliser read, mais gardez à l'esprit que les deux head/tail et read sont des fonctions partielles et peuvent échouer sur une liste vide. Je pense qu'il est préférable d'éviter head si vous pouvez utiliser la correspondance de modèle à la place. Par exemple,

get3rd :: String -> String 
get3rd s = 
    case (take 3 $ words s) of 
    [_,_,w] -> w 
    otherwise -> "" 

Cette fonction est sans danger pour toute entrée (il retourne juste une chaîne vide s'il y a moins de 3 mots). Certainement, si vous êtes absolument sûr que les listes sont toujours non vides, vous pouvez utiliser head/tail.

Avec read vous pouvez attraper des exceptions (pas très pratique), ou utiliser reads à la place:

toInt :: String -> Maybe Int 
toInt s = 
    case reads s of 
    [(i,_)] -> Just i 
    otherwise -> Nothing 

-- test cases 
main = do 
    print . toInt . get3rd $ "1 2 3" 
    print . toInt . get3rd $ "one two three" 
    print . toInt . get3rd $ "short list" 

Ce toInt retours Just un numéro ou Nothing si elle ne peut pas analyser. Vous pouvez également utiliser Safe library et sa fonction readMay.

+1

Vous devriez ajouter que c'est parfaitement bien d'utiliser 'last' et' head' tant que vous savez avec certitude que vous ne traiterez pas une liste vide. – Rayne

+0

Je suis d'accord Rayne et mis à jour la réponse. – sastanin

0

Vous les gars sont bien, mais je poste parce que je pense qu'il est une fonction très élégante et utile je suis venu avec lors de l'apprentissage pour aider à la lecture ING et montrent ment du texte.

as :: (Read a, Show a) => (a -> a) -> String -> String 
as f = show . f . read 

Prelude> as (+1) "7" 
"8" 

Prelude> as (+(1/2)) "5" 
"5.5" 

Utile, hein? = P. Aussi xs !! n obtient le nième élément de xs. Regardez d'autres réponses pour des moyens faciles à imprimer.

+0

Pourquoi pas '(Lire a, Montrer b) => (a -> b) -> Chaîne -> Chaîne' comme type? – sepp2k

+0

Touche. Le vôtre a du sens, je suppose que je l'ai fait pour la simplicité. – codebliss