我的程序是用 Python 3 编写的,它有很多地方都以(非常大的)类似表的数字数据结构开始,并按照某种算法向其中添加列。(算法在每个地方都不一样。)
我正在尝试将其转换为纯函数式方法,因为我遇到了命令式方法的问题(难以重用、难以记忆中间步骤、难以实现“惰性”计算、由于依赖状态而容易出错等) .
该类Table
被实现为字典字典:外部字典包含行,索引为row_id
; 内部包含一行中的值,由 . 索引column_title
。该表的方法非常简单:
# return the value at the specified row_id, column_title
get_value(self, row_id, column_title)
# return the inner dictionary representing row given by row_id
get_row(self, row_id)
# add a column new_column_title, defined by func
# func signature must be: take a row and return a value
add_column(self, new_column_title, func)
到目前为止,我只是在原始表中添加了列,每个函数都将整个表作为参数。当我转向纯函数时,我必须使所有参数不可变。因此,初始表变得不可变。任何其他列都将创建为独立列,并仅传递给需要它们的那些函数。一个典型的函数会获取初始表和一些已经创建的列,并返回一个新列。
我遇到的问题是如何实现独立列(Column
)?
我可以给他们每个人做一本字典,但它似乎很贵。事实上,如果我需要对每个逻辑行中的 10 个字段执行操作,我将需要进行 10 次字典查找。最重要的是,每一列都将包含键和值,使其大小增加一倍。
我可以制作Column
一个简单的列表,并在其中存储对从 row_id 到数组索引的映射的引用。好处是这个映射可以在对应于同一个初始表的所有列之间共享,并且一旦查找一次,它就适用于所有列。但这会产生任何其他问题吗?
如果我这样做,我可以更进一步,并将映射实际存储在初始表本身中吗?我可以将Column
对象的引用放回创建它们的初始表吗?它似乎与我想象的一种功能性工作方法大不相同,但我看不出它会导致什么问题,因为一切都是不可变的。
一般来说,函数式方法是否不赞成在返回值中保留对其中一个参数的引用?看起来它不会破坏任何东西(比如优化或惰性评估),因为无论如何这个参数都是已知的。但也许我错过了一些东西。