使用Haskell中的代码进行类似Lisp的配置

时间:2011-10-31 13:49:17

标签: haskell

我正在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中编写一个解析器。谢谢!

3 个答案:

答案 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"