我正在尝试使用Haskell来搜索网页并将结果编译成一个对象.
如果由于某种原因,我无法从页面中获取所有项目,我想停止尝试处理页面并提前返回.
例如:
scrapePage :: String -> IO ()
scrapePage url = do
doc <- fromUrl url
title <- liftM headMay $ runX $ doc >>> css "head.title" >>> getText
when (isNothing title) (return ())
date <- liftM headMay $ runX $ doc >>> css "span.dateTime" ! "data-utc"
when (isNothing date) (return ())
-- etc
-- make page object and send it to db
return ()
Run Code Online (Sandbox Code Playgroud)
问题是when不会停止执行阻止或保持其他部分不被执行.
这样做的正确方法是什么?
我参与了这个项目,Pinta,我们目前正在使用GitHub进行开发.我们都喜欢Git和GitHub,并希望继续使用它.然而,现在项目变得稳定并且参与其中,我们开始使用比GitHub的简单问题跟踪器更强大的错误跟踪系统.我们还想开始进行基于GetText的翻译.
我们正在寻找具有良好的错误跟踪器和翻译管理器的Launchpad,但我们希望继续使用GitHub进行开发.我担心这些不能很好地整合,它会使开发变得更难.
有没有人使用GitHub与另一个bug跟踪系统并取得了成功?有什么建议?
我希望能够确保函数在接收到无效值时会抛出错误.例如,假设我有一个只返回正数的函数pos:
pos :: Int -> Int
pos x
| x >= 0 = x
| otherwise = error "Invalid Input"
Run Code Online (Sandbox Code Playgroud)
这是一个简单的例子,但我希望你能得到这个想法.
我希望能够编写一个期望出现错误的测试用例并将其视为通过测试.例如:
tests = [pos 1 == 1, assertError pos (-1), pos 2 == 2, assertError pos (-2)]
runTests = all (== True) tests
Run Code Online (Sandbox Code Playgroud)
[我的解决方案]
这是我最终根据@ hammar的评论进行的.
instance Eq ErrorCall where
x == y = (show x) == (show y)
assertException :: (Exception e, Eq e) => e -> IO a -> IO ()
assertException ex action =
handleJust isWanted …Run Code Online (Sandbox Code Playgroud) 有没有办法在没有变量的情况下写这个x?
foo = do
x <- checker bar
when x dostuff
Run Code Online (Sandbox Code Playgroud)
我在想象类似于LambdaCase的东西:
foo' = do
checker bar >>= \case
True -> dostuff
_ -> return ()
Run Code Online (Sandbox Code Playgroud)
但显然没有第二种情况模式.
如何让Haskell在同一端口上侦听UDP和TCP?
这是我到目前为止的代码(基于acme-http):
listenOn portm = do
protoTCP <- getProtocolNumber "tcp"
E.bracketOnError
(socket AF_INET Stream protoTCP)
sClose
(\sock -> do
setSocketOption sock ReuseAddr 1
setSocketOption sock NoDelay 1
bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)
listen sock (max 1024 maxListenQueue)
return sock
)
protoUDP <- getProtocolNumber "udp"
E.bracketOnError
(socket AF_INET Datagram protoUDP)
sClose
(\sock -> do
setSocketOption sock ReuseAddr 1
bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)
return sock
)
Run Code Online (Sandbox Code Playgroud)
我编译得很好,但是我得到了跟随运行时错误:
user error (accept: can't perform accept on socket ((AF_INET,Datagram,17)) in status Bound) …Run Code Online (Sandbox Code Playgroud) 抱歉这个措辞不好的标题,但我甚至不知道如何正确地问它.
我怎么能这个呢?
instPublicIP :: Instance -> Maybe Text
instPublicIP inst =
inst ^. insNetworkInterfaces ^? ix 0 . iniAssociation . _Just . iniaPublicIP . _Just
Run Code Online (Sandbox Code Playgroud)
进入这个
instPublicIP' :: Lens' Instance (Maybe Text)
instPublicIP' = insNetworkInterfaces ^? ix 0 . iniAssociation . _Just . iniaPublicIP . _Just
Run Code Online (Sandbox Code Playgroud)
当我尝试时,我收到以下错误:
Main.hs:198:3:
Couldn't match expected type ‘(Maybe Text -> f (Maybe Text))
-> Instance -> f Instance’
with actual type ‘Maybe Text’
Relevant bindings include
instPublicIP' :: (Maybe Text -> f (Maybe Text))
-> …Run Code Online (Sandbox Code Playgroud) 我正在研究我在这里工作的项目:
我在我的函数中使用monad变换器方法看起来像这样:
scrapePost :: String -> IO ()
scrapePost url = liftM (fromMaybe ()) . runMaybeT $ do
doc <- lift $ fromUrl url
-- get a bunch of stuff from the page
-- send it to the db
replies <- lift . runX $ doc >>> css ".post.reply"
-- here is the problem
mapM_ (parseReply url (fromJust page_id)) replies
-- here is the problem
Run Code Online (Sandbox Code Playgroud)
parseReply 是我需要的功能,但我似乎无法做到正确.
这是我开始这个功能的微弱尝试:
parseReply :: String -> String -> XNode -> Maybe ()
parseReply …Run Code Online (Sandbox Code Playgroud) 我一直在我的python代码中执行此操作.我愿意打赌有一种更容易(也就是一线)的方式来做到这一点.
results = getResults()
if len(results) > 0:
result = results[0]
Run Code Online (Sandbox Code Playgroud)
我实际上并不需要其他地方的"结果",我应该只运行一次"getResults".
有任何想法吗?
我正在尝试处理来自请求解析器的异常:
go bs =
case try $ parseRequest reader bs secure of
Left ex -> exceptionHandler writer ex
Right (request, bs') -> do
sendResponse writer =<< app request
go bs'
Run Code Online (Sandbox Code Playgroud)
但是在使用时我遇到了一个问题try:
Couldn't match expected type `IO (Either e0 (Request, ByteString))'
with actual type `Either t0 t1'
In the pattern: Left ex
In a case alternative: Left ex -> exceptionHandler writer ex
In the expression:
case try $ parseRequest reader bs secure of {
Left ex -> exceptionHandler writer …Run Code Online (Sandbox Code Playgroud) 我处于不幸的情况,我需要直接在Haskell中与Java套接字API连接.通过线路发送Java字符串的方式是将它们的长度添加到字符串的开头.
例如:
\0\0\0\xBHello World
Run Code Online (Sandbox Code Playgroud)
是字符串"Hello World"
我可以得到ByteString没有问题的长度,但作为一个Int.我可以Word32使用Blaze Builder向ByteString 添加一个,但我找不到一种方便的方法来转换Int为Word32.有没有一些方便的方法我找不到这样做?
谢谢.
我有一个选项记录,我需要转换成命令行参数.
例如:
data Options = Options { optFoo :: Maybe Int
, optYes :: Bool
, optBar :: Maybe String
}
options = Options { optFoo = Just 3
, optYes = True
, optBar = Nothing
}
callThing :: Options -> IO ()
callThing opts = do
callProcess "/usr/bin/thing" $ optsToArgs opts
-- Output should be: ["--foo", "3", "-y"]
optsToArgs :: Options -> [String]
optsToArgs opts = ???
Run Code Online (Sandbox Code Playgroud)
我想象能够使用List Monad,但我无法弄清楚如何让它工作.
在我的特定情况下,Options中有大约20种不同的东西,因此使用嵌套的if/case语句的解决方案并不理想.
有没有解决这类问题的共同模式?
这是基于我较早前的问题的建议,在这里:
go bs = do
r <- try $ parseRequest reader bs secure
case r of
Left ex -> do
putStrLn "got exception"
exceptionHandler writer ex
go empty
Right (request, bs') -> do
sendResponse writer =<< app request
go bs'
Run Code Online (Sandbox Code Playgroud)
当没有异常时,右边部分没有问题.但是,当抛出异常时,异常会一直冒泡到顶部,而Left则不会运行.它似乎并不是什么样的例外.
以下是它应该捕获的异常(尽管它也不会捕获error):
data ParseError
= Unexpected
| MalformedRequestLine ByteString
| MalformedHeader ByteString
| MissingHeader ByteString Headers
| UnknownSIPVersion ByteString
deriving (Typeable, Show, Eq)
instance Exception ParseError
Run Code Online (Sandbox Code Playgroud)
这是exceptionHandler的类型:
exceptionHandler :: (ByteString -> IO ())
-> ParseError
-> …Run Code Online (Sandbox Code Playgroud) haskell ×10
binary ×1
bug-tracking ×1
bytestring ×1
git ×1
github ×1
haskell-lens ×1
hunit ×1
hxt ×1
lenses ×1
monads ×1
open-source ×1
python ×1
tcp ×1
testing ×1
translation ×1
udp ×1
unit-testing ×1
web-scraping ×1