Haskell 使用getChanContents从Chan收集所有结果

Haskell 使用getChanContents从Chan收集所有结果,haskell,concurrency,channels,Haskell,Concurrency,Channels,我在Haskell玩。我想并行执行一些IO操作,直到其中一个操作失败,然后将所有结果收集到一个列表中 此代码错误,出现异常。如何让它与getChanContents一起工作?我看到的所有示例都假设他们知道频道上有多少条消息 有没有一种更干净的方法来收集员工的大量结果 module UrlPatterns where import Control.Concurrent import Types import Text.HTML.Scalpel import Data.Monoid ((<&

我在Haskell玩。我想并行执行一些
IO
操作,直到其中一个操作失败,然后将所有结果收集到一个列表中

此代码错误,出现
异常
。如何让它与
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
模块模式,其中
导入控制。并发
导入类型
导入Text.HTML.sparcel
导入数据。Monoid(())
进口管制.Concurrent.Chan
导入控制
导入数据。可能(isJust,catMaybes)
导入数据列表(takeWhile)
--查找符合以下模式的域下的所有有效链接:
-- http://example.com/pages/(1..N)
--一旦有一个不见了,就返回一份你找到的所有人的名单
findIncrementing::URL->IO[链接]
findIncrementing base=do
设num=1
--查找频道
cfind IO(可能是字符串)
findPageTitle url=scrapeURL url scrapeTitle
页面URL::URL->Int->URL
pageUrl base num=基本显示num

感谢@bartavelle。我有一个与频道代码无关的错误。以下是相关的修复程序:

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

return links
——收集结果

结果当您得到
Exception
时,通常意味着您在
let
子句中编写了一个递归项,例如
let results=take,而isJust results::[可能链接]
。。。这就解释了为什么它不起作用,我想:)似乎这应该是一个编译时错误。又吸取了一个教训<代码>getChanContents
在GHC 7.10上也可能会被破坏,因此它实际上不可能是编译时错误,因为这样的表达式是完全有效的:
让a=1:a
。但如果使用
-Wall
编译,则应该有编译警告。