Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Bytestring question (Daniel Fischer) 2. Re: Bytestring question (Peter Braun) 3. Looking for some Haskell Monad Code Examples (patricklynch) 4. Re: Looking for some Haskell Monad Code Examples (aditya siram) 5. Re: Looking for some Haskell Monad Code Examples (Henk-Jan van Tuyl) 6. Re: Looking for some Haskell Monad Code Examples (Karol Samborski) 7. Trying to use map (Michael Litchard) 8. Re: Trying to use map (Daniel Fischer) ---------------------------------------------------------------------- Message: 1 Date: Wed, 26 Jan 2011 14:28:25 +0100 From: Daniel Fischer <daniel.is.fisc...@googlemail.com> Subject: Re: [Haskell-beginners] Bytestring question To: beginners@haskell.org Message-ID: <201101261428.25915.daniel.is.fisc...@googlemail.com> Content-Type: text/plain; charset="iso-8859-1" On Wednesday 26 January 2011 01:52:33, Peter Braun wrote: > Hi everyone, > > as an exercise for learning Haskell i'm writing a program that converts > Ascii Stl files (a simple format for 3D model data) into binary Stl > format. In my first attempt i used normal strings and the result was > therefore very slow. Now i rewrote the program to use lazy bytestrings > instead. > > But well... it got even slower, so i'm probably doing something terribly > wrong ;) > > Here's what i do (the relevant parts): > > ... > asciiFile <- L.readFile (args!!0) > binHandle <- openBinaryFile (args!!1) WriteMode > let asciiLines = L.split (c2w '\n') asciiFile > ... > parseFile binHandle (Normal, tail asciiLines) -- First line contains a > comment > ... > > where L is Data.ByteString.Lazy. readFile ought to be lazy so it should > not read the whole file into ram at this point. But when i split the > lines and pass them to a function, is this still carried out lazily? Yes, readFile reads a chunk and only proceeds to read the next when it is required. I'm not sure how lazy split is exactly, it could stop at the first newline or it could split the entire chunk in one go, but that wouldn't make much difference either way. > > parseFile processes a line, depending on the StlLineType and then calls > itself recursive like this: > > parseFile :: Handle -> (StlLineType, [L.ByteString]) -> IO () Shouldn't the type better be parseFile :: Handle -> StlLineType -> [L.ByteString] -> IO () ? > ... > parseFile h (Vertex1, s) = do > let vals = extractVertex (head s) > L.hPutStr h $ runPut (writeFloatArray vals) > parseFile h (Vertex2, tail s) pattern match, please parseFile h (Vertex1, []) = return () -- or what you have to do at the end parseFile h (Vertex1, (l:ls)) = do let vals = extractVertex l L.hPutStr $ runPut (writeFloatArray vals) parseFile h (Vertex2, ls) > ... > > extractVertex looks like this: > > extractVertex :: L.ByteString -> [Float] > extractVertex s = let fracs = filter (\n -> L.length n > 0) $ L.split > (c2w ' ') s > in [read (C.unpack(fracs!!1)) :: > Float, Ouch, if you're unpacking everything, what's the point of using ByteStrings? And splitting ByteStrings is sort of expensive too. Okay, trouble is, there's no obvious way to parse a Float from a ByteString, but bytestring-lexing provides parsing Doubles, you could use that and convert the Doubles to Floats with GHC.Float.double2Float (or, if you have optimisations turned on, with realToFrac, which should then be rewritten to double2Float). That should be much faster than unpacking and using read (particularly since the Read instances of Float and Double are slow). > read (C.unpack(fracs!!2)) > > :: Float, > > read (C.unpack(fracs!!3)) > > :: Float] Instead of list-indexing with (!!), pattern matching gives nicer code. > > where C is Data.ByteString.Lazy.Char8. It splits a byte string, filters > out the whitespaces and converts certain entries to floats. Maybe unpack > is an expensive operation. Is there a better way to convert a Bytestring > to float? You could also try using attoparsec and write a real parser for your file, that should be pretty snappy. attoparsec also provides double :: Parser Double (no direct parsing of Float provided), you could then again call double2Float on the result. > > I know, this is bad Haskell code ;) But where is my grand, obvious > misuse of Bytestring? Lots of splitting into small pieces and lots of unpacking. Both add up to considerable cost. I suspect also read to take a substantial amount of the time, but you also have that for String IO. > > I'm grateful for any suggestion to improve that code. I'm using ghc, > version 6.12.1. > > Thank you, > Peter ------------------------------ Message: 2 Date: Wed, 26 Jan 2011 19:37:18 +0100 From: Peter Braun <peter-br...@gmx.net> Subject: Re: [Haskell-beginners] Bytestring question To: beginners@haskell.org Message-ID: <4d4069de.2030...@gmx.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Thanks for your reply. Attoparsec seems to be the perfect tool for the job and i will ultimately try to implement my converter utilizing it. But i also installed bytestring-lexing and will try this out, just to see if i can gain some performance when eliminating the suboptimal reads / unpacks. Thanks for the tip! Shouldn't the type better be parseFile :: Handle -> StlLineType -> [L.ByteString] -> IO () Yes, there really is no reason for using a tuple. I'll also eliminate the usage of (!!) and function calls where pattern matching is possible. ------------------------------ Message: 3 Date: Wed, 26 Jan 2011 15:41:43 -0500 From: "patricklynch" <kmandpjly...@verizon.net> Subject: [Haskell-beginners] Looking for some Haskell Monad Code Examples To: <beginners@haskell.org> Message-ID: <657fe5f6dc4b46cf87a5a89391aae...@stsv.com> Content-Type: text/plain; charset=US-ASCII Good afternoon, ...can anyone provide me with a references that shows Haskell code examples of Monads? ... I've read the references but I need some actual code snippets to check to see if I really understand Monads. Thank you ------------------------------ Message: 4 Date: Wed, 26 Jan 2011 14:19:26 -0600 From: aditya siram <aditya.si...@gmail.com> Subject: Re: [Haskell-beginners] Looking for some Haskell Monad Code Examples To: patricklynch <kmandpjly...@verizon.net> Cc: beginners@haskell.org Message-ID: <aanlktik7euj2xmks2siqh38z-p+yittffsp3dzrkf...@mail.gmail.com> Content-Type: text/plain; charset=ISO-8859-1 Learn You A Haskell [1] and Real World Haskell [2] are great resources. -deech [1] http://learnyouahaskell.com/a-fistful-of-monads [2] http://book.realworldhaskell.org/read/monads.html On Wed, Jan 26, 2011 at 2:41 PM, patricklynch <kmandpjly...@verizon.net> wrote: > Good afternoon, > > ...can anyone provide me with a references that shows Haskell code examples > of Monads? > > ... I've read the references but I need some actual code snippets to check > to see if I really understand Monads. > > Thank you > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > ------------------------------ Message: 5 Date: Wed, 26 Jan 2011 22:20:17 +0100 From: "Henk-Jan van Tuyl" <hjgt...@chello.nl> Subject: Re: [Haskell-beginners] Looking for some Haskell Monad Code Examples To: beginners@haskell.org, patricklynch <kmandpjly...@verizon.net> Message-ID: <op.vpxpj3xypz0...@zen5.arnhem.chello.nl> Content-Type: text/plain; charset=iso-8859-15; format=flowed; delsp=yes On Wed, 26 Jan 2011 21:41:43 +0100, patricklynch <kmandpjly...@verizon.net> wrote: > Good afternoon, > > ...can anyone provide me with a references that shows Haskell code > examples > of Monads? See "A tour of the Haskell Monad functions": http://members.chello.nl/hjgtuyl/tourdemonad.html Regards, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ http://members.chello.nl/hjgtuyl/tourdemonad.html -- ------------------------------ Message: 6 Date: Wed, 26 Jan 2011 22:44:32 +0100 From: Karol Samborski <edv.ka...@gmail.com> Subject: Re: [Haskell-beginners] Looking for some Haskell Monad Code Examples To: patricklynch <kmandpjly...@verizon.net> Cc: beginners@haskell.org Message-ID: <AANLkTi=0riMuUVGQ=jpff9qazg1j2okjkyrgbx8h7...@mail.gmail.com> Content-Type: text/plain; charset=UTF-8 I'm a Haskell beginner and monads become clear to me after reading the "Real World Haskell" book so I fully recommend it ;) Regards, Karol Samborski 2011/1/26 patricklynch <kmandpjly...@verizon.net>: > Good afternoon, > > ...can anyone provide me with a references that shows Haskell code examples > of Monads? > > ... I've read the references but I need some actual code snippets to check > to see if I really understand Monads. > > Thank you > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners > ------------------------------ Message: 7 Date: Wed, 26 Jan 2011 14:51:18 -0800 From: Michael Litchard <mich...@schmong.org> Subject: [Haskell-beginners] Trying to use map To: beginners@haskell.org Message-ID: <AANLkTinh6U0gehJAKT4ky5t=bwehdmxiatbrhvczt...@mail.gmail.com> Content-Type: text/plain; charset="iso-8859-1" Here's what I'm working with, followed by what I am trying to do, and the type error I get. I'm leaving things out that I do not think are important. Let me know if I'm missing nessecary info. > curlResp > :: (MonadError String m, MonadIO m) > => Curl -> URLString -> [CurlOption] -> m String --CurlResponse > curlResp curl url opts = do > resp <- liftIO $ (do_curl_ curl url opts :: IO CurlResponse) > let code = respCurlCode resp > status = respStatus resp > if code /= CurlOK || status /= 200 > then throwError $ "Error: " ++ show code ++ " -- " ++ show status > else return $ respBody resp > screenScraping :: String -> [String] > screenScraping responseBody = > let collectedStrings = processHTML responseBody > collectedIDLists = createIDList collectedStrings > in constructedResourceURIs urlBase collectedIDLists > resourceOpts :: [CurlOption] > resourceOpts = > [ CurlHttpHeaders > [ "Accept: text/javascript, text/html, application/xml, text/xml, */*" > , "Accept-Language: en-us,en;q=0.5" > , "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" > , "Keep-Alive: 115" > , "Connection: keep-alive" > , "X-Requested-With: XMLHttpRequest" > , "X-Prototype-Version: 1.6.0.3" > ] > , CurlEncoding "gzip,deflate" > ] > obtainCookies :: IO Curl -> String -> IO () > obtainCookies curl responseBody = do > curl' <- curl > let collectedResources = screenScraping responseBody > in mapM ( curlResp curl' resourceOpts) collectedResources > return () > main :: IO () > main = do > curl <- initCurl > user:pass:_ <- getArgs > resp <- generateResourceHtml user pass > > case resp of > Left err -> print err > Right body -> obtainCookies curl body Here's the error I get. Couldn't match expected type `Char' against inferred type `CurlOption' Expected type: URLString Inferred type: [CurlOption] In the second argument of `curlResp', namely `resourceOpts' In the first argument of `mapM', namely `(curlResp curl' resourceOpts)' The problem I see is a misformed mapM. I am trying to do something like this curlResp curl' resourceOpts "-here-be-a-url" where collectedResources is a [String]. Not sure how to map over it correctly. The other problem I see is this > obtainCookies :: IO Curl -> String -> IO () > obtainCookies curl responseBody = do > curl' <- curl > let collectedResources = screenScraping responseBody > in mapM ( curlResp curl' resourceOpts) collectedResources > return () this function does a monadic action (all I want is the cookies) and I don't need the return value. I am not sure that the final line return (), is what I want. My primary question is this. how do I map over collectedResources correctly? Secondary question, is the return correct? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://www.haskell.org/pipermail/beginners/attachments/20110126/eba919f5/attachment-0001.htm> ------------------------------ Message: 8 Date: Thu, 27 Jan 2011 00:13:51 +0100 From: Daniel Fischer <daniel.is.fisc...@googlemail.com> Subject: Re: [Haskell-beginners] Trying to use map To: beginners@haskell.org Message-ID: <201101270013.51978.daniel.is.fisc...@googlemail.com> Content-Type: text/plain; charset="utf-8" On Wednesday 26 January 2011 23:51:18, Michael Litchard wrote: > Here's what I'm working with, followed by what I am trying to do, and > the type error I get. I'm leaving things out that I do not think are > important. Let me know if I'm missing nessecary info. > > > > > > obtainCookies :: IO Curl -> String -> IO () > > obtainCookies curl responseBody = do > > curl' <- curl > > let collectedResources = screenScraping responseBody > > in mapM ( curlResp curl' resourceOpts) > > collectedResources > Looks like you need a flip here: in mapM (flip (curlResp curl') resourceOpts) collectedResources > > return () If you're throwing away the results of the MapM'ed actions, use mapM_ obtainCookies curl responseBody = do curl' <- curl mapM_ (flip (curlResp curl') resourceOpts) $ screenScraping responseBody > > this function does a monadic action (all I want is the cookies) and I > don't need the return value. I am not sure that the final line return > (), is what I want. > > > My primary question is this. how do I map over collectedResources > correctly? Secondary question, is the return correct? Use mapM_ ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 31, Issue 33 *****************************************