您将如何在 Elm 中构建电子表格应用程序?
How would you structure a spreadsheet app in elm?
我一直在关注 elm,我真的很喜欢学习这门语言。我一直在考虑做一个电子表格应用程序,但我无法理解它的结构。
假设我们有三个单元格; A、B 和 C。
如果我在单元格 A 中输入 4
并在单元格 B 中输入 =A
如何让单元格 B 始终等于单元格 A?如果我然后在单元格 C 中输入 =A+B
,是否可以将其计算为 8
,并在 A 或 B 更改时也进行更新?
不确定如何利用信号来实现这种动态行为。
问候奥斯卡
首先,您需要决定如何表示电子表格网格。如果您有 C 语言背景,您可能想使用二维数组,但我发现字典在 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
解析会有点棘手; String module 是你的朋友。 Eval 将涉及通过电子表格追踪引用并递归地填充结果。起初你会想要忽略捕获无限循环的可能性。另外,这只是一个草图,如果您发现不同的类型签名效果更好,请使用它们。
至于视图,我将从只读开始,这样您就可以验证硬编码电子表格是否已正确评估。然后你可以担心编辑,你只需重新运行解析器和求值器并获得一个新的电子表格来呈现。它应该可以工作,因为电子表格除了每个单元格的内容外没有其他状态。 (最小化重新计算的工作是您可以扩展它的许多不同方法之一。)如果您使用的是 elm-html,table 元素应该没问题。
希望这能让您朝着正确的方向前进。这是一个雄心勃勃的项目,我很乐意在您完成后看到它(post 它到 mailing list)。祝你好运!
我一直在关注 elm,我真的很喜欢学习这门语言。我一直在考虑做一个电子表格应用程序,但我无法理解它的结构。
假设我们有三个单元格; A、B 和 C。
如果我在单元格 A 中输入 4
并在单元格 B 中输入 =A
如何让单元格 B 始终等于单元格 A?如果我然后在单元格 C 中输入 =A+B
,是否可以将其计算为 8
,并在 A 或 B 更改时也进行更新?
不确定如何利用信号来实现这种动态行为。
问候奥斯卡
首先,您需要决定如何表示电子表格网格。如果您有 C 语言背景,您可能想使用二维数组,但我发现字典在 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
解析会有点棘手; String module 是你的朋友。 Eval 将涉及通过电子表格追踪引用并递归地填充结果。起初你会想要忽略捕获无限循环的可能性。另外,这只是一个草图,如果您发现不同的类型签名效果更好,请使用它们。
至于视图,我将从只读开始,这样您就可以验证硬编码电子表格是否已正确评估。然后你可以担心编辑,你只需重新运行解析器和求值器并获得一个新的电子表格来呈现。它应该可以工作,因为电子表格除了每个单元格的内容外没有其他状态。 (最小化重新计算的工作是您可以扩展它的许多不同方法之一。)如果您使用的是 elm-html,table 元素应该没问题。
希望这能让您朝着正确的方向前进。这是一个雄心勃勃的项目,我很乐意在您完成后看到它(post 它到 mailing list)。祝你好运!