1

Je suis un nouveau à la programmation fonctionnelle. Je suis en train de gratter un site Web en utilisant Scalpel et j'ai besoin d'extraire des informations à partir des liens contenus dans ce site. Ce que je peux extrapoler est juste une partie du lien et je dois ajouter à la chaîne "http://www.google.com/" à chacun de ces liens. Je ne peux pas faire un ++ normal parce que je n'ai pas une liste de String s.Comment pouvez-vous ajouter une chaîne à une liste de Monades dans Haskell

Voici le code:

{-# LANGUAGE OverloadedStrings #-} 

import Text.HTML.Scalpel 

main :: IO() 
main = do 
    res <- scrapeURL "http://www.whateverLink/" scrapeComic 
    print res 

scrapeComic :: Scraper String [[String]] 
scrapeComic = 
    chroots ("ul" @: ["id" @= "research-teachinglist"]) scrapeLink 

scrapeLink :: Scraper String [String] 
-- This returns me the parts of the links I want 
scrapeLink = (attrs "href" "a") 

-- I tried this, but it doesn't work 
-- scrapeLink = mapM_ ("http://www.google.com/" ++) (attrs "href" "a") 

Toutes les idées?

Merci

+4

'fmap (carte ("http://www.google.com/" ++)) scrapeLink', mais vous devriez probablement jeter un coup d'œil à la typeclassopedia. Cette question demande plus ou moins un tutoriel sur la monade, qui est hors-sujet sur SO. – Zeta

+0

Cela a fonctionné! Je vais regarder quelques tutoriels de monade. Merci – BourbonCreams

Répondre

1

Vous avez

attrs "href" "a" :: Scraper String [String] 

et

("http://www.google.com/" ++) :: String -> String 

et vous souhaitez appliquer ce dernier à tous les String éléments dans la liste des résultats de la première.

tout d'abord, en l'appliquant à des listes est une question de

map :: (a -> b) -> [a] -> [b] 

donc dans votre cas, vous avez

map ("http://www.google.com/" ++) :: [String] -> [String] 

Ce qui nous amène un pas de plus.

Maintenant le problème suivant est qu'au lieu d'une valeur [String] pure, vous avez un calcul Scraper String [String]. Cependant, Scraper str is an instance of Functor pour tout choix de str, en particulier, pour str ~ String, c'est-à-dire Scraper String est un Functor.

Qu'est-ce qui nous donne est une façon d'appliquer des fonctions pures à Scraper String s:

fmap :: (a -> b) -> Scraper String a -> Scraper b 

en particulier, nous avons

fmap (map ("http://www.google.com/" ++)) :: Scraper String [String] 

conduisant à

scrapeLink :: Scraper String [String] 
scrapeLink = fmap (map ("http://www.google.com/" ++)) (attrs "href" "a")