nandor / hcraft

Haskell clone of a certain game
MIT License
95 stars 6 forks source link

added Wavefront .OBJ parser in Renderer.Mesh.OBJ #4

Open stnma7e opened 10 years ago

stnma7e commented 10 years ago

I am in the process of learning haskell, but I saw this project and looked through the code. It seemed fairly simple, but I saw a lot of things to learn :). I added this OBJ parser based on one I had written in Go for my own project. I had more to add to the parser, but as I read through how it was being used, I just left it at parsing vertices.

Feel free to criticize and change my work, because I'm still learning. For instance, I know the "case of -> case of ->" stack of code could be condensed, but I didn't figure it out.

nandor commented 10 years ago

You should try to replace the use of head with pattern matching.

case words line of
   "v" : ws -> ...
   "vn" : ws -> ...
   "vt" : ws -> ...
   _ -> ...

To simplify the case blocks, you can use the maybe monad:

getX, getY, getZ :: a -> Maybe GLFloat
vector = do
  x <- getX
  y <- getY
  z <- getZ
  return [ Vec3 x y z ]
stnma7e commented 10 years ago

Hey. I updated the OBJ parser and simplified it. I took some of your advice, but I had a question on the syntax of this:

case words line of
   "v" : ws -> ...
   "vn" : ws -> ...
   "vt" : ws -> ...
   _ -> ...

I used this snippet, however, I don't understand the syntax of '"v" : ws ->'. What is colon operator in this context, and what is ws? I looked on Hoogle, but I didn't find anything, and Google gave me more or less the same.

If you could give me a write back that'd be awesome.

nandor commented 10 years ago

"v":ws matches all the lists of strings which begin with the string "v", pointing ws to the tail of the list. For example, if you have line = "v 0 1 2", words line yields ["v", "0", "1", "2"] which will match that pattern because the head of the list is "v". In that case, ws will be ["0", "1", "2"].