我正在Haskell中编写一个光线跟踪器,目前,我在代码中定义了我的场景,如下所示:
(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))])
这在表达性方面非常有效,而且它很棒,因为我不必编写任何类型的解析器,但这意味着每次我想渲染不同的场景时都必须重新编译。我通过Lisp来到Haskell,这将是简单的(加载文件,评估内容,然后渲染结果)但我认识到Haskell的特性使得即使不是不可能,也很难。
你是否有更多经验丰富的Haskeller有任何关于解决这个问题的最佳方法的建议?在理想的世界中,我的代码外部有一些文件,用Haskell语法定义了我可以加载的场景;在最不理想的世界里,我可能会在Parsec中编写一个解析器。谢谢!
答案 0 :(得分:7)
如果您确保所有data
都是Read
(... deriving Read
)的实例,那么您可以read them :: Withatypeifnecessary
。
中间解决方案是使用json;解析比使用Parsec更容易,但当然它比代码中的read
更难。
更新:如果存在非构造函数,read
方法将无效。
答案 1 :(得分:1)
在这种情况下,您可以简单地使用read
(假设一切都deriving Read
)。它显然有点笨拙,但它可能会有用(而且它的工作量不如走向parsec路线)。
答案 2 :(得分:0)
如何使用像Hint这样的haskell解释器?不可否认,这并不像在lisp中那么容易,你需要格外小心,使用与描述场景相同的模块编译渲染器,但它仍然可以正常工作,即使它不是真正的Haskell方式做事。
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"