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 :

Haskell et HTTP


Sujet :

Haskell

  1. #1
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut [résolu] Haskell et HTTP
    Comme je l'ai indiqué,ici je me suis mis à l'apprentissage de Haskell. Je ne suis qu'un programeur amateur, et mes progrès sont laborieux, mais j'avance...

    En fouinant sur planet.haskell.org/, je suis tombé sur ce post d'un blog :
    http://www.deanberris.com/mental-bla...nd-monads.html

    et je veux tester le code proposé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    --HTTP
     
    --So let's say you want to impress your friends and want to pull your blog's front page and dump it out to the screen. How do we do it? Simple:
     
        import Network.HTTP
        import Network.URI
        import Data.Maybe
     
        main =
          do
              resp <- simpleHTTP request
              case resp of
                Left x -> printStrLn ("Error connecting: " ++ show x)
                Right r ->
                  case rspCode r of
                    (2,_,_) -> printStrLn ( rspBody r )
                    _ -> printStrLn ("Got response status other than 2XX!")
          where request = Request {
                                         rqURI = uri,
                                         rqMethod = GET,
                                         rqHeaders = [],
                                         rqBody = ""
                                      } 
                     uri = fromJust $ parseURI "http://www.deanberris.com/"
     
    --And that's it!
    J'ai donc mis ça dans un fichier .hs, et je teste sous GHCI :
    me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    :23:17:
        parse error on input `='
    Failed, modules loaded: none.
    (:23:17 correspond au tout dernier signe = du code : "uri = etc)
    quelqu'un voit d'où ça vient ?

    Par ailleurs, je ne comprends pas l'utilisation du $ (en général, et ici en particulier)

  2. #2
    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 586
    Points
    8 586
    Par défaut
    Haskell a une syntaxe qui prend en compte l'indentation... Ici l'ensemble de ton module est indenté, alors qu'il commence usuellement à la première colonne. Je suppose que tu as simplement fait un copier-coller.
    Le problème est que les définitions de uri et request ne sont pas indentés identiquement alors qu'ils devraient appartenir au même bloc, uri est plus indenté que request donc la ligne commençant par uri est considéré comme une continuation de la définition de request et une expression ne peut pas contenir de "=".
    Les règles d'indentations de Haskell sont très simples, je peux te faire un résumé si tu le souhaites ?

    Par ailleurs ce code est un peu compliqué pour une simple requête GET :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    module Main where
     
    import Network.URI
    import Network.HTTP.Simple
    import Data.Maybe
    import Control.Monad
     
    main = do
      page <- justGet "http://www.google.fr"
      putStrLn page
     
    justGet :: String -> IO String
    justGet s = liftM (fromMaybe (error $ "The GET request for " ++ s ++ " failed.\n"))
                $ httpGet
                  $ fromMaybe (error $ s ++ " is not a valid URI.\n")
                    $ parseURI s

    ($) est un opérateur à la définition extrêmement simple :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ($) :: (a -> b) -> a -> b
    f $ x = f x
    Autrement dit c'est simplement l'application de fonction, comme un simple espace. Mais l'intérêt de ($) vient de sa priorité très faible, ce qui permet d'éviter d'utiliser beaucoup de parenthèses, par exemple ma fonction justGet ressemblerait à ça sans ($) :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    justGet :: String -> IO String
    justGet s = liftM (fromMaybe (error ("The GET request for " ++ s ++ " failed.\n")))
                  (httpGet (fromMaybe (error (s ++ " is not a valid URI.\n")) (parseURI s)))
    Ce qui peut convenir aux adeptes du Lisp mais a tendance à irriter la plupart des gens... Je ne trouve pas ça très lisible non plus.
    Tu peux lire le ($) comme un pipe à l'envers, plus ou moins.

    --
    Jedaï

  3. #3
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par Jedai Voir le message
    Haskell a une syntaxe qui prend en compte l'indentation... Ici l'ensemble de ton module est indenté, alors qu'il commence usuellement à la première colonne. Je suppose que tu as simplement fait un copier-coller.
    Le problème est que les définitions de uri et request ne sont pas indentés identiquement alors qu'ils devraient appartenir au même bloc, uri est plus indenté que request donc la ligne commençant par uri est considéré comme une continuation de la définition de request et une expression ne peut pas contenir de "=".
    OK, je vais essayer avec la bonne indentation... à suivre (edit : j'ai un autre pb, voir message suivant)

    Citation Envoyé par Jedai Voir le message
    Les règles d'indentations de Haskell sont très simples, je peux te faire un résumé si tu le souhaites ?
    Merci.En fait je vais réviser dans Real World Haskell, je reposterai une question si besoin, mais je pense que ça ira ...
    Citation Envoyé par Jedai Voir le message
    Par ailleurs ce code est un peu compliqué pour une simple requête GET :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    module Main where
     
    import Network.URI
    import Network.HTTP.Simple
    import Data.Maybe
    import Control.Monad
     
    main = do
      page <- justGet "http://www.google.fr"
      putStrLn page
     
    justGet :: String -> IO String
    justGet s = liftM (fromMaybe (error $ "The GET request for " ++ s ++ " failed.\n"))
                $ httpGet
                  $ fromMaybe (error $ s ++ " is not a valid URI.\n")
                    $ parseURI s
    je vais tester, ça me fera creuser le sujet ...
    Citation Envoyé par Jedai Voir le message
    ($) est un opérateur à la définition extrêmement simple :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ($) :: (a -> b) -> a -> b
    f $ x = f x
    Autrement dit c'est simplement l'application de fonction, comme un simple espace. Mais l'intérêt de ($) vient de sa priorité très faible, ce qui permet d'éviter d'utiliser beaucoup de parenthèses, par exemple ma fonction justGet ressemblerait à ça sans ($) :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    justGet :: String -> IO String
    justGet s = liftM (fromMaybe (error ("The GET request for " ++ s ++ " failed.\n")))
                  (httpGet (fromMaybe (error (s ++ " is not a valid URI.\n")) (parseURI s)))
    Ce qui peut convenir aux adeptes du Lisp mais a tendance à irriter la plupart des gens... Je ne trouve pas ça très lisible non plus.
    Tu peux lire le ($) comme un pipe à l'envers, plus ou moins.

    --
    Jedaï
    Merci de la précision, je n'avais pas bien compris, c'est clair maintenant ...

  4. #4
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    ok, j'ai donc indenté correctement la définition de uri.

    je refais le :load , et ghci me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    :12:18:
        Not in scope: `printStrLn'
    (message répété pour les autres printStrLn)

    euh, comment je fais pour avoir printStrLn ? (et où dois-je chercher la prochaine fois ?)

    j'ai aussi testé ta version, qui me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Could not find module `Network.HTTP.Simple':
    ... pas très doué, je disais ...
    ce qui est vraiment bizarre, c'est que "import Network.HTTP" ne me renvoie pas de message d'erreur
    tiens je viens de faire
    qui me renvoie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Network                 Network.HTTP.Headers    Network.StreamSocket
    Network.BSD             Network.Socket          Network.TCP
    Network.Browser         Network.Stream          Network.URI
    Network.HTTP            Network.StreamDebugger  Numeric
    je suis sous Ubuntu et j'ai installé via Synaptic : libghc6-http-dev en version : 30010004-2

    j'ai juste là ? où quelque chose a échappé à mon oeil de lynx myope et débutant ?

  5. #5
    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 586
    Points
    8 586
    Par défaut
    printStrLn n'existe pas, la fonction correcte est putStrLn.

    Network.HTTP.Simple est dans le package HTTP-Simple, pas dans le package http normal. Si tu as installé cabal-install (hautement recommandé), tu peux l'installer d'un simple "cabal install HTTP-Simple".

    --
    Jedaï

  6. #6
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par Jedai Voir le message
    printStrLn n'existe pas, la fonction correcte est putStrLn.
    OK ça marche maintenant ... il ne me reste plus qu'à comprendre comment !
    Citation Envoyé par Jedai Voir le message
    Network.HTTP.Simple est dans le package HTTP-Simple, pas dans le package http normal. Si tu as installé cabal-install (hautement recommandé), tu peux l'installer d'un simple "cabal install HTTP-Simple".

    --
    Jedaï
    Ah ... c'est là que le bât blesse : je tente d'installer cabal, et mon Synaptic (Ubuntu 8.04)
    me répond :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    libghc6-cabal-dev:
      Dépend*: ghc6 (<6.6.1+) mais 6.8.2-2ubuntu1 doit être installé
    et là je suis perdu car quand je lance ghci, il m'indique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
    Loading package base ... linking ... done.
    hmmm ... tu as un conseil pour moi ?

  7. #7
    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 586
    Points
    8 586
    Par défaut
    Ce paquet cabal est visiblement vieux, de plus il ne concerne pas cabal-install (le binaire) mais cabal (la librairie). Suis donc plutôt les instructions du lien que je t'ai donné, il y a même une instruction apt-get pour Ubuntu pour installer les dépendances.

    --
    Jedaï

  8. #8
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    Citation Envoyé par Jedai Voir le message
    Ce paquet cabal est visiblement vieux, de plus il ne concerne pas cabal-install (le binaire) mais cabal (la librairie). Suis donc plutôt les instructions du lien que je t'ai donné, il y a même une instruction apt-get pour Ubuntu pour installer les dépendances.

    --
    Jedaï
    OK je l'ai fait ...
    alors encore un peu de chinois (pour moi) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ./cabal install HTTP-Simple
    Resolving dependencies...
    Downloading HTTP-Simple-0.1...
    [1 of 1] Compiling Main             ( /tmp/HTTP-Simple-0.17310/HTTP-Simple-0.1/Setup.lhs, /tmp/HTTP-Simple-0.17310/HTTP-Simple-0.1/dist/setup/Main.o )
    Linking /tmp/HTTP-Simple-0.17310/HTTP-Simple-0.1/dist/setup/setup ...
    Configuring HTTP-Simple-0.1...
    Warning: No 'build-type' specified. If you do not need a custom Setup.hs or
    ./configure script then use 'build-type: Simple'.
    Preprocessing library HTTP-Simple-0.1...
    Building HTTP-Simple-0.1...
    [1 of 1] Compiling Network.HTTP.Simple ( Network/HTTP/Simple.hs, dist/build/Network/HTTP/Simple.o )
     
    Network/HTTP/Simple.hs:69:22:
        Not in scope: type constructor or class `ConnError'
    cabal: Error: some packages failed to install:
    HTTP-Simple-0.1 failed during the building phase. The exception was:
    exit: ExitFailure 1
    ta patience est admirable Jedai (ou bien "la patience du Jedai admirable elle est")

  9. #9
    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 586
    Points
    8 586
    Par défaut
    Il apparait que HTTP-Simple s'appuie sur l'interface de la version 3xxx du package HTTP mais oublie malencontreusement de le préciser dans ses dépendances.
    A ce stade il y a deux remèdes possibles, adapter la librairie à la dernière version de HTTP (ce qui requiert deux modifications mineures du code, avec un peu d'expérience c'est l'affaire d'une minute de trouver les corrections et de les appliquer, comme je l'ai fait), ou compléter le fichier HTTP-Simple.cabal pour lui indiquer que "HTTP < 4000" est la dépendance correcte, pas HTTP.

    Je vais envoyer le patch au mainteneur, mais d'ici là tu peux adopter l'une des solutions ci-dessus ou simplement te passer des quelques fonctions de HTTP-Simple et utiliser directement HTTP.

    --
    Jedaï

  10. #10
    Membre régulier
    Inscrit en
    Mai 2005
    Messages
    140
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 140
    Points : 84
    Points
    84
    Par défaut
    Merci Jedaï, tu m'as bien aidé... je ne suis pas sûr de faire les manips que tu dis pour l'instant, mais je me débrouillerai pour l'instant...

    je passe le post en [résolu]

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. site web sur le Haskell
    Par ab_sam dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 30/09/2003, 12h11
  2. [SSL]Communication avec un serveur en https
    Par menon dans le forum Développement Web en Java
    Réponses: 3
    Dernier message: 04/09/2003, 16h38
  3. [HTTP] Wget-like
    Par tmonjalo dans le forum Développement
    Réponses: 2
    Dernier message: 28/07/2003, 13h39
  4. [HTTP] Syntaxe méthode POST
    Par Gruik dans le forum Développement
    Réponses: 3
    Dernier message: 26/07/2003, 17h12
  5. [web] rapatrier un document via HTTP
    Par ddhia dans le forum Web
    Réponses: 2
    Dernier message: 08/04/2003, 11h01

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