1

HaskellでChannelsをいじっています。いずれかのIOアクションが失敗するまでいくつかのアクションを並行して実行し、すべての結果をリストに収集したいと考えています。

このコードは でエラーになりException <<loop>>ます。どうすればそれを動作させることができgetChanContentsますか? 私が見たすべての例は、チャネルにあるメッセージの数を知っていることを前提としています。

ワーカーから一連の結果を収集するよりクリーンな方法はありますか?

module UrlPatterns where

import Control.Concurrent
import Types
import Text.HTML.Scalpel
import Data.Monoid ((<>))
import Control.Concurrent.Chan
import Control.Applicative
import Data.Maybe (isJust, catMaybes)
import Data.List (takeWhile)


-- find all valid links under a domain that follow the pattern:
-- http://example.com/pages/(1..N)
-- as soon as one is missing, return a list of all the ones you found
findIncrementing :: URL -> IO [Link]
findIncrementing base = do

    let num = 1

    -- find channel
    cfind <- newChan
    writeChan cfind (base, num)

    -- results channel
    cdone <- newChan

    forkIO $ worker cfind cdone

    -- collect the results
    results <- getChanContents cdone
    let results = takeWhile isJust results :: [Maybe Link]
    print results

    return []


worker :: Chan (URL, Int) -> Chan (Maybe Link) -> IO ()
worker next done = loop
  where 
    loop = do
      (base, num) <- readChan next
      let url = pageUrl base num
      putStrLn $ "FETCHING: " <> url

      mt <- findPageTitle url

      case mt of
        Nothing -> do
          writeChan done Nothing
          putStrLn ("Missed " <> show num)
        Just t  -> do
          writeChan done $ Just $ Link url t
          writeChan next (base, num+1)

      loop

scrapeTitle :: Scraper String String
scrapeTitle = text "title"

findPageTitle :: URL -> IO (Maybe String)
findPageTitle url = scrapeURL url scrapeTitle

pageUrl :: URL -> Int -> URL
pageUrl base num = base <> show num
4

1 に答える 1

2

@bartavelle に感謝します。チャンネルコードとは無関係のエラーが発生しました。関連する修正は次のとおりです。

-- collect the results
results <- getChanContents cdone
let links = catMaybes $ takeWhile isJust results

return links
于 2015-04-08T17:07:53.423 に答える