2012-04-26 39 views
7

我一直在思考如何在Haskell中构建一个WPF或AngularJS模型的MVC框架,但似乎无法找到关键类型或想法获得开始。所以很不幸含糊的问题 - 有没有其他人一直在想这个问题?Haskell MVC框架镜头

我看到编辑镜头,多板和Compos,但我认为他们都解决了稍有不同的问题。

我如何将工作将草图:

  1. 创建一个模型作为一个普通的Haskell数据结构
  2. 创建一组的“镜头”或命令来修改模型。
  3. 编写一个HTML模板(或其他),这个模板由模型中的类型参数化。

data Model = Page { _title :: String, _content :: [(Int, String)] } 

title :: Lens Model String 
content :: Int -> Lens Model (Maybe String) 

然后,我会希望能够写一个函数:

Model -> Template Model -> Html 

和功能时,我申请一个镜头来更新我的观点的部分。

Lens Model a -> a -> HtmlTemplate Model -> [(Path, Html)] 

所以我想的问题是 - 将一个镜头拍什么类型的,可以在一个数据结构进行操作,然后被用来描述在其他的变化。

一种可能性似乎是创建一个包装所有镜头的GADT,然后在GADT类型上对HTML进行模板化,然后可以在每一步使用该模板匹配模板。例如

data Lenses a b where 
    Title :: Lens Model String -> Lenses Model String 
    Item :: Lens Model String -> Lenses Model (Maybe String) 

然后,Html模板数据类型例如

data HtmlTemplate a = Text String 
       | Element String [Attrib a] 
       | forall b. Binding (Lenses a b) (Html b) 

Binding元素可以与其直接模式匹配。

但是,这似乎几乎击败了这一点,因为模型然后在臀部加入视图。

我想知道有人(比我聪明)想出了这可能如何工作?或者即使这是一个好主意?

+1

我已经开始了一个实验镜头库,旨在支持任意有效的操作,您可能有兴趣查看这些操作(目前不推荐您使用它,因为API将会改变,它是实验性的,而且是圆滑的在reddit上讨论它时)。最接近你的案例将是[本文]中的最后一个例子(http://brandon.si/code/yall/);当你在模型上做Lens操作时,你可能希望在'State'中修改你的视图:'LensM(State View)Model a'或类似的东西。但我还没有使用MVC模式太多,所以请原谅我,如果我关闭 – jberryman 2012-04-26 22:23:45

+0

我认为这至少是解决方案的一半,以便您可以构建对视图的更改(或直接修改视图) 。不过我想我缺少的是一种机制来同时遍历模型和视图(模板模型) - 某种拉链来同时遍历两个相关结构。 – Oliver 2012-04-27 03:36:38

+0

你可能会对http://www.haskellforall.com/2014/04/model-view-controller-haskell-style.html – hdgarrood 2014-04-27 19:47:29

回答

9

我一直在Haskell中使用基于镜头的“MVC”构建大型商业应用程序。

  • 纯功能性数据结构
  • 透镜设置和获取(并保持数据一致)
  • 用于产生依赖于每个透镜的图(模板)的DSL。

这是一个很好的经验,我绝对推荐用于复杂结构的详细结构编辑的方法。你

的方法势力

  • 没本事,但使用的镜头是安全的接口,你的内部模型
  • 模型的强分离 - >查看
  • 类型检查一切 - 镜头类型生成视图代码

有很多方法可以设计它,但我认为这是一个非常合理的设计方法。您将需要为GUI部分提供良好的DSL支持。

+2

感兴趣吗?你可以详细说明一下:“用于生成与每个镜头相关的视图(模板)的DSL 。“?听起来很酷。 – jberryman 2012-04-26 22:31:02

+1

基本上是一种模板语言,它将屏幕上的类型化控件与其对应的镜头相关联。因此,按钮,文本输入,数字输入等可以链接到该输入的编辑镜头,并且可以连接这些镜头的图形。用户界面然后就掉了。 – 2012-04-27 11:30:12

+0

听起来不错。我想使用类似的方法将Html作为UI使用本地Web应用程序。 (或者有一天UHC Javascript)。欢呼声:) – Oliver 2012-04-27 12:15:20