Re: [Haskell-cafe] [Pipes] Can pipes solve this problem? How?
On Wed, Aug 15, 2012 at 9:54 PM, Daniel Hlynskyi abcz2.upr...@gmail.comwrote: Hello Cafe. Consider code, that takes input from handle until special substring matched: matchInf a res s | a `isPrefixOf` s = reverse res matchInf a res (c:cs) = matchInf a (c:res) cs hTakeWhileNotFound str hdl = hGetContents hdl = return.matchInf str [] It is simple, but the handle is closed after running. That is not good, because I want to reuse this function. Code can be rewritten without hGetContent, but it is much less comprehensible: hTakeWhileNotFound str hdl = fmap reverse$ findStr str hdl [0] [] where findStr str hdl indeces acc = do c - hGetChar hdl let newIndeces = [ i+1 | i - indeces, i length str, str!!i == c] if length str `elem` newIndeces then return (c : acc) else findStr str hdl (0 : newIndeces) (c : acc) So, the question is - can pipes (any package of them) be the Holy Grail in this situation, to both keep simple code and better deal with handles (do not close them specifically)? How? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe This is essentially what we do in wai-extra for multipart body parsing[1]. This code uses `conduit`. The tricky part is that you have to remember that the substring you're looking for might be spread across multiple chunks, so you need to take that into account. A simple approach would be: * If the search string is a substring of the current chunk, success. * If the end of the current chunk is a prefix of the search string, grab the next chunk, append the two, and repeat. (Note: there are more efficient approaches than appending.) * Otherwise, skip to the next chunk. * If no more chunks available, the substring was not found. Michael [1] https://github.com/yesodweb/wai/blob/master/wai-extra/Network/Wai/Parse.hs#L270 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] [Pipes] Can pipes solve this problem? How?
On 12-08-15 02:54 PM, Daniel Hlynskyi wrote: Hello Cafe. Consider code, that takes input from handle until special substring matched: matchInf a res s | a `isPrefixOf` s = reverse res matchInf a res (c:cs) = matchInf a (c:res) cs hTakeWhileNotFound str hdl = hGetContents hdl = return.matchInf str [] So, the question is - can pipes (any package of them) be the Holy Grail in this situation, to both keep simple code and better deal with handles (do not close them specifically)? How? It's more complex than Pipes, but SCC gives you what you need. If you cabal install it, you have the choice of using the shsh executable on the command line to accomplish your task: $ shsh -c 'cat input-file.txt | select prefix (! substring search string)' or using the equivalent library combinators from Haskell code: import System.IO (Handle, stdin) import Control.Monad.Coroutine (runCoroutine) import Control.Concurrent.SCC.Sequential pipeline :: String - Handle - Producer IO Char () pipeline str hdl = fromHandle hdl - select (prefix $ sNot $ substring str) hTakeWhileNotFound :: String - Handle - IO String hTakeWhileNotFound str hdl = fmap snd $ runCoroutine $ pipe (produce $ pipeline str hdl) (consume toList) main = hTakeWhileNotFound up to here stdin = putStrLn ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] [Pipes] Can pipes solve this problem? How?
Hello Cafe. Consider code, that takes input from handle until special substring matched: matchInf a res s | a `isPrefixOf` s = reverse res matchInf a res (c:cs) = matchInf a (c:res) cs hTakeWhileNotFound str hdl = hGetContents hdl = return.matchInf str [] It is simple, but the handle is closed after running. That is not good, because I want to reuse this function. Code can be rewritten without hGetContent, but it is much less comprehensible: hTakeWhileNotFound str hdl = fmap reverse$ findStr str hdl [0] [] where findStr str hdl indeces acc = do c - hGetChar hdl let newIndeces = [ i+1 | i - indeces, i length str, str!!i == c] if length str `elem` newIndeces then return (c : acc) else findStr str hdl (0 : newIndeces) (c : acc) So, the question is - can pipes (any package of them) be the Holy Grail in this situation, to both keep simple code and better deal with handles (do not close them specifically)? How? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe