IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Haskell Discussion :

retourner un (Maybe Float -> Float -> Float)


Sujet :

Haskell

  1. #1
    Futur Membre du Club
    Inscrit en
    avril 2011
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : avril 2011
    Messages : 9
    Points : 9
    Points
    9
    Par défaut retourner un (Maybe Float -> Float -> Float)
    Bonjour,

    Je démarre tout justeavec Haskell. Je développe quelques petits programmes pour me faire la main. J'ai fait un evaluateur de notation polonaise inversée qui fonctionne bien mais j'aimerais l'améliorer avec l'utilisation de Maybe notamment. Et c'est là que je butte.

    Je voudrais avoir une fonction qui me retourne une fonction Float-> Float->Float à partir d'un nom de fonction ( (+) pour "+" par exemple)
    et rien (Nothing) si la fonction n'est pas connue.

    Mon implémentation actuelle est la suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    operation :: String -> Maybe Float -> Float -> Float
    operation op 
       | op == "+" = Just (+)
       | op == "-" = Just (-)
       | op == "*" = Just (*)
       | op == "/" = Just (/)
       | otherwise = Nothing
    Mais la compilation échoue :

    rpn.hs:64:18:
    Couldn't match expected type `Maybe Float -> Float -> Float'
    with actual type `Maybe a0'
    In the expression: Nothing
    In an equation for `operation':
    operation op
    | op == "+" = Just (+)
    | op == "-" = Just (-)
    | op == "*" = Just (*)
    | op == "/" = Just (/)
    | otherwise = Nothing


    je ne comprends pas ce que je loupe. Dois je typer explictement le Nothing ? si oui comment ?
    Ou alors n'ai je pas bien compris le Maybe ?

    Merci d'avance pour votre aide


    Olivier

  2. #2
    Futur Membre du Club
    Inscrit en
    avril 2011
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : avril 2011
    Messages : 9
    Points : 9
    Points
    9
    Par défaut
    J'ai trouvé comment réussir une compilation de ma fonction :

    operation :: String -> Maybe (Float -> Float -> Float)
    operation op
    | op == "+" = Just (+)
    | op == "-" = Just (-)
    | op == "*" = Just (*)
    | op == "/" = Just (/)
    | otherwise = Nothing

    Le paranthésage semble résoudre l'erreur de compilation.
    mais maintenant j'échoue à l'execution avec l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    *Main> (operation "+") 2.0 2.0
     
    <interactive>:3:1:
        Couldn't match expected type `Double -> Double -> t'
                    with actual type `Maybe (Float -> Float -> Float)'
        Relevant bindings include it :: t (bound at <interactive>:3:1)
        The function `operation' is applied to three arguments,
        but its type `String -> Maybe (Float -> Float -> Float)'
        has only one
        In the expression: (operation "+") 2.0 2.0
        In an equation for `it': it = (operation "+") 2.0 2.0
    ou encore ::

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    *Main> (Just (operation "+")) 2.0 2.0
     
    <interactive>:3:1:
        Couldn't match expected type `Double -> Double -> t'
                    with actual type `Maybe (Maybe (Float -> Float -> Float))'
        Relevant bindings include it :: t (bound at <interactive>:3:1)
        The function `Just' is applied to three arguments,
        but its type `Maybe (Float -> Float -> Float)
                      -> Maybe (Maybe (Float -> Float -> Float))'
        has only one
        In the expression: (Just (operation "+")) 2.0 2.0
        In an equation for `it': it = (Just (operation "+")) 2.0 2.0

  3. #3
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : avril 2003
    Messages : 6 245
    Points : 8 560
    Points
    8 560
    Par défaut
    Comme tu l'as compris, ta première signature était équivalente à "String -> (Maybe Float) -> Float -> Float" car l'application (ici de Maybe) est toujours prioritaire (ici par rapport à l'opérateur ->).

    Maintenant ton problème est que tu essaies d'appliquer (operation "+") comme si c'était une fonction mais c'est un Maybe qui contient (éventuellement) une fonction...

    Pour l'appliquer, il y a plusieurs possibilités :

    Extraire la fonction dans un pattern match :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    case operation "+" of
      Just f -> f 2 2
      Nothing -> error "opération inconnue"
    ou dans GHCi sur une seule ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    case operation "+" of {Just f -> f 2 2; Nothing -> error "opération inconnue"}
    Tu peux également utiliser le fait que Maybe est un Functor pour traiter les deux cas de façon transparente :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fmap (\f -> f 2 2) (operation "+")
    Attention toutefois, cette fois ci le résultat sera du type "Maybe Float" (Just résultat ou Nothing si l'opération est inconnue).

    Ceci peut également s'écrire de la façon suivante avec la monade Maybe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    do
      f <- operation "+"
      return (f 2 2)
    La façon dont tu procèdes dépendra de tes besoins (la monade est par exemple parfaite si tu as d'autres source de Maybe, par exemple pour les opérandes, et que tu veux les combiner en obtenant Nothing dès que l'un d'entre eux échoue).

    Dernière façon de faire, ici appropriée parce que tu sais que l'opération existe (mais alors pourquoi ne pas utiliser directement (+) ...) mais à éviter en général :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import Data.Maybe (fromJust)
     
    ... (fromJust (operation "+")) 2 2
    Bonne continuation.
    --
    Jedaï

Discussions similaires

  1. retourner la partie décimale d'un float
    Par sheridan08 dans le forum Général Python
    Réponses: 12
    Dernier message: 16/04/2014, 11h48
  2. retourner un résultat float en deux décimales
    Par hamdi.hassane.03 dans le forum Requêtes
    Réponses: 1
    Dernier message: 07/06/2013, 17h51
  3. [PHP 5.3] round retourne un float invalide (-0)
    Par max-mag dans le forum Langage
    Réponses: 2
    Dernier message: 12/09/2012, 09h31
  4. un float random entre 2 float
    Par denis.ws dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 20/03/2008, 15h16
  5. probleme d'insertion d'un Float
    Par neness dans le forum Débuter
    Réponses: 3
    Dernier message: 07/01/2003, 13h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo