记录的通用方法 [英] Generic method on record

查看:97
本文介绍了记录的通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有更好的方法来实现接受记录并对其进行修改的功能.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆