我正在开发一个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.


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

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的组合?如果没有,那么对于我的情况有什么更好的方法?

最佳答案

您可以使用if ... then ... else

例如,

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

10-06 02:43