我一直在看榆树,我真的很喜欢学习这门语言。我一直在考虑做一个电子表格应用程序,但我无法理解它的结构。
假设我们有三个细胞; A,B和C.
如果我在单元格A中输入4
而在单元格B中输入=A
,我将如何使单元格B始终等于单元格A?如果我然后在单元格C中输入=A+B
,是否可以将其评估为8
,并在A或B更改时更新?
不知道如何杠杆信号这种动态行为..
关心奥斯卡
答案 0 :(得分:5)
首先,您需要决定如何表示电子表格网格。如果你来自C背景,你可能想要使用2D数组,但我发现字典在Elm中实际上效果更好。因此,您可以定义type alias Grid a = Dict (Int, Int) a
。
对于a
,每个单元格拥有什么......这是定义特定于域的语言的机会。像
type Expr = Lit Float | Ref (Int, Int) | Op2 (Float -> Float -> Float) Expr Expr
这意味着表达式是文字浮点数,对另一个单元格位置的引用或运算符。运算符可以是两个浮点数上的任何函数,另外两个表达式可以递归计算。根据您的目的,您可以为每个操作定义特定的标记,例如Plus Expr Expr | Times Expr Expr
,或者您可以为不同的操作添加额外的opN标记(如否定)。
那么你可以定义type alias Spreadsheet = Grid Expr
,如果你想将(Int, Int)
别名,那也可能有所帮助。我还假设你只想在电子表格中使用浮点数。
现在您需要将字符串转换为表达式并返回的函数。这些函数的传统名称是parse
和eval
。
parse : String -> Maybe Expr -- Result can also work
eval : Spreadsheet -> Grid Float
evalOne : Expr -> Spreadsheet -> Maybe Float
Parse会有点棘手; String module是你的朋友。 Eval将涉及通过电子表格追踪引用并递归填写结果。首先,你要忽略捕获无限循环的可能性。此外,这只是一个草图,如果您发现不同类型的签名更好用,请使用它们。
至于视图,我从只读开始,因此您可以验证硬编码的电子表格是否正确评估。然后你可以担心编辑,我的想法是你只需重新运行解析器和评估器并获得一个新的电子表格来呈现。它应该工作,因为电子表格没有除每个单元格的内容之外的状态。 (最小化重新计算的工作是你可以扩展它的许多不同方法之一。)如果你使用elm-html,表元素应该没问题。
希望这会让你朝着正确的方向前进。这是一个雄心勃勃的项目,我很乐意在你完成后看到它(发布到mailing list)。祝你好运!