正如我在评论中提到的,如果你有一个不可变的作者列表并在其上映射,你实际上并没有最终复制所有作者。不改变的作者将只是指向同一个实例(因此不可变解决方案的开销并不大)。
但是,如果您有多本同一作者的书籍,则确实没有别名,因此作者都是单独的值(并且您必须映射所有书籍)。
我认为在这种情况下,一个合理的表示是保持作者和书籍分开,并通过一个键(例如作者姓名 - 在下面的示例中 - 或其他一些 ID)链接它们:
type Author = { Name : string; Address : string }
type Book = { Title : string; Author : string }
// For efficient lookup, create a hashtable with authors
let authors = dict [ "Tomas", { Name = "Tomas"; Address = "Cambridge" } ]
// Books are stored simply as a list
let books = [ { Title = "Real World FP"; Author = "Tomas" } ]
// To get nice access, add AuthorDetails property to the Author record
type Book with
member x.AuthorDetails = authors.[x.Author]
for book in books do
printfn "%s (%s, %s)" book.Title book.Author book.AuthorDetails.Address
这不会让您改变集合authors
。如果您以纯函数方式编写此代码,您可能会有一些递归函数将当前作者作为参数,因此您不需要突变(只需构建一个新字典)。
但我认为有一个ref
值来保存字典,甚至保留一个可变字典是合理的(但我只会在你没有并发的情况下这样做;事实上,在存在并发的情况下,Map
可能是更安全的选择)。