Lisp -like configuration using code in Haskell

I am writing a raytracer in Haskell, and currently I define my scene in code like this:

(Scene [(Sphere (Vec3 1 0 0) 4 (PhongMaterial (color 1 0 0) (color 1 1 1) 4))] [(PhongLight (Vec3 0 0 0) (color 1 1 1) (color 1 1 1))]) 

This works very well in terms of expressiveness, and it's great because I don’t need to write any parser, but that means I have to recompile every time I want to display a different scene. I came to Haskell through Lisp, where it would be simple (upload a file, eval contents, and then visualize the result), but I admit that Haskell has traits that make this, if not impossible, then very complicated.

Do any of you more experienced Haskellers have any suggestions on the best way to solve this? In an ideal world, I would have a file external to my code that would define a scene in Haskell syntax that I could load; in the least ideal world, I could write a parser in Parsek. Thanks!

+6
source share
3 answers

If you make sure that all your data are instances of Read (... deriving Read ), you can just read them :: Withatypeifnecessary .

An intermediate solution would be to use json ; parsing is simpler than using Parsec, but of course it is a bit more complicated than just Read entry in the code.


Update: if non-constructor functions exist, the Read approach will not work.

+7
source

In this case, you could just use read (assuming that deriving Read does everything). This is obviously a bit awkward, but most likely it will work (and it works less than descending the parsek).

+1
source

How to use a haskell interpreter like hint ? Admittedly, this is not as easy as in lisp, and you need to be especially careful that you compile the renderer with the same modules as for describing your scenes, but still it could work fine, although this is not entirely Haskell does something.

  main :: IO () main = do [a] <- getArgs r <- runInterpreter (loadScene a) case r of Left err -> printInterpreterError err Right scene -> raytrace scene loadScene :: Filepath -> Interpreter () loadScene fn = do loadModules [fn] eval "name_of_variable_describing_scene_in_my_source" 
0
source

Source: https://habr.com/ru/post/900437/


All Articles