Haskell是否有'when`和`unless`的组合?

时间:2017-08-15 15:50:06

标签: haskell monads

我正在开发一个TCP客户端,它从流中获取指定类型的消息,并且只是发现我自己使用很多,除非和表达式。例如:

hunt :: Socket -> ThreadId -> IO ()                               
hunt conn t = do threadDelay 1000000
                 msg <- recv conn 1024
                 unless (C.isInfixOf "1b14010102" $ encode msg) $ hunt conn t
                 when (C.isInfixOf "1b14010102" $ encode msg) $ do
                     threadDelay 7000000
                     sendAll conn $ goHunt
                     msg <- recv conn 1024
                     threadDelay 3000000
                     close conn
                     killThread t

我正在尝试构建一个帮助器,如:

waitfor :: ByteString -> Socket -> t -> (ByteString -> Socket -> t -> IO ()) -> IO ()
waitfor str conn tid f = do 
    threadDelay 1000000
    msg <- recv conn 1024
    let m = C.isInfixOf str msg
    unless m $ waitfor str conn tid f
    when m $ f msg conn tid

然后我可以重新使用帮助器:

main = do
    ...
    tid <- myThreadId
    conn <- joinWorld u
    waitfor "1b14010102" conn tid hunt.

但如果我有另一个功能(它需要3个参数,而不是hunt

hunt' :: ByteString -> Socket -> ThreadId -> IO ()
hunt' idx conn t = do threadDelay 1000000
                      msg <- recv conn 1024
                      unless (C.isInfixOf "0300aa0801" $ encode msg) $ hunt' conn t
                      when (C.isInfixOf "0300aa0801" $ encode msg) $ do
                          threadDelay 1000000
                          sendAll conn $ goHunt' idx
                          threadDelay 3000000
                          close conn
                          killThread t

然后我无法使用waitfor,需要再次使用when / unless。那么,Haskell是否有when / unless的组合?如果没有,那么对我的案例有什么更好的方法呢?

1 个答案:

答案 0 :(得分:7)

您可以使用waitfor :: ByteString -> Socket -> t -> (ByteString -> Socket -> t -> IO ()) -> IO () waitfor str conn tid f = do threadDelay 1000000 msg <- recv conn 1024 if C.isInfixOf str msg then waitfor str conn tid f else f msg conn tid

例如,

{{1}}