记录的通用方法 [英] Generic method on record
问题描述
我想知道是否有更好的方法来实现接受记录并对其进行修改的功能.
I wonder if there is a better way of implementing a function that accepts records and modify them.
所以我有两种类型的实体,它们在磁盘上都有对应的文件:
So I have entities of two types, both have corresponding files on the disk:
type Picture = { Artist : string; File : string }
type Book = { Author : string; File : string }
我想要可以复制图片和书籍的通用函数.在OOP世界中,我可能会创建公共接口IArtefact { File : string }
,在两个记录中都实现它,然后创建在其上起作用的Move方法.像这样:
I want generic function that can copy both pictures and books. In the OOP world I would probably create common interface IArtefact { File : string }
, implement it in both records and then create Move method that works on it. Something like:
let move<'a:IArtefact>(a : 'a) (path : string) =
File.Move(a.File, path)
{ a with File = path }
但是,我认为F#不支持这种概念. F#这样做的方式是什么?
However I suppose that F# does not support such concept. What is the F# way of doing so?
推荐答案
虽然没有通用的更改记录复制方法,但是有一种方法可以移动具有File
的任何内容:
While there is no generic way of change-copying records, there is one for moving anything that has a File
:
let inline move from where : string =
let oldFile = (^T : (member File : string) from)
do() // move here
where
type Picture = { Artist: string; File: string }
type Book = { Author: string; File: string }
let p = { Artist = "Vincent van Gogh"; File = "Rooftops" }
let p' = { p with File = move p "The Potato Eaters" }
let b = { Author = "Don Syme"; File = "Generics in CLR" }
let b' = { b with File = move b "Expert F#" }
然后可以将其扩展为移动任何知道如何移动的东西:
This could then be expanded to move anything that knows how to be moved:
let inline move' a where =
let oldFile = (^T : (member File : string) a)
do() // move here
(^T: (member moved : string -> ^T) a, where)
type Picture' =
{ Artist: string; File: string } with
member this.moved where = { this with File = where }
type Book' =
{ Author: string; File: string } with
member this.moved where = { this with File = where }
let p2 = { Artist = "Vincent van Gogh"; File = "Rooftops" }
let p2' = move' p2 "The Potato Eaters"
let b2 = { Author = "Don Syme"; File = "Generics in CLR" }
let b2' = move' b2 "Expert F#"
这篇关于记录的通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!