У меня есть Conduit типа Conduit a m a
и функция типа (a -> Maybe a)
. Я хочу запустить функцию, а затем, если она ничего не возвращает, использовать Conduit. То есть я хочу функцию типа
maybePipe :: Conduit a m b -> (a -> Maybe b) -> Conduit a m b
или, более ограниченного типа
maybePipe :: Conduit a m a -> (a -> Maybe a) -> Conduit a m a
Если это поможет, мой конкретный случай выглядит следующим образом:
Я пишу код, который работает с сообщениями IRC, и у меня есть функция:
runClient :: Conduit IRC.Message IO IRC.Message -> ClientSettings -> IO ()
runClient pipe address = runTCPClient' pipe' address where
pipe' = mapC IRC.decode $= concatMapC id $= pipe $= mapC IRC.encode $= mapC (++ "\r\n")
handlePings (IRC.Message (Just (IRC.Server serverName)) "PING" []) = Just $ IRC.pong serverName
handlePings (IRC.Message Nothing "PING" [server]) = Just $ IRC.pong server
handlePings (IRC.Message Nothing "PING" []) = Just $ IRC.pong (getHost address)
handlePings _ = Nothing
runTCPClient' :: Conduit ByteString IO ByteString -> ClientSettings -> IO ()
runTCPClient' pipe address = runTCPClient address runClient where
runClient appdata = appSource appdata $= linesUnboundedAsciiC $= pipe $$ appSink appdata
Я хочу иметь возможность выполнять maybePipe handlePings pipe
(или эквивалент) в этой функции, поэтому, когда сообщение IRC представляет собой ping, мы отвечаем pong и не вызываем указанный пользователем Conduit.