F#和鸭子打字 [英] F# and duck-typing
问题描述
type Dog = {DogName:string;年龄:int}
类型Cat = {CatName:string; Age:int}
我期待以下方法适用于猫和狗:
let isOld x = x.Age> = 65
实际上,似乎发生的情况是 isOld
只会接受猫:
let dog = {DogName =Jackie;年龄= 4}
let cat = {CatName =Micky;年龄= 80}
让isDogOld = isOld dog //错误
我的希望F#能够聪明地为猫和狗定义某种虚拟接口 X
,这样 isOld
会接受X作为参数,而不是 Cat
。
这不是F#在任何情况下都能处理的事情,对吗?看起来F#类型推断系统不会做什么比C#用 var
类型变量做什么更多。
您可以使用成员约束来定义 inline
函数,也可以使用经典路由并使用接口(这可能会首选
let inline isOld(x:^ T)=(^ T:(member Age:int)x) > = 65
编辑
I只记得这不适用于记录类型。从技术上讲,他们的成员是领域,但您可以使用与成员......
修改成员。您必须这样做才能满足界面。
作为参考,您将如何实现与记录类型的接口:
type IAging =
抽象年龄:int
类型Dog =
{DogName:string
Age:int}
接口IAng与
成员this.Age = //也可以是`this.Age = this.Age`
let {DogName = _;年龄=年龄=本次
年龄
Let's say I defined in F# the following two types:
type Dog = { DogName:string; Age:int }
type Cat = { CatName:string; Age:int }
I was expecting the following method to work for both cats and dogs:
let isOld x = x.Age >= 65
Actually, what seems to happen is that isOld
will only accept cats:
let dog = { DogName = "Jackie"; Age = 4 }
let cat = { CatName = "Micky"; Age = 80 }
let isDogOld = isOld dog //error
My hopes were that F# would be smart enough to define some kind of "virtual" interface X
for both cats and dogs so that isOld
would accept a X as argument, instead of a Cat
.
This isn't something that F# will in any circumstance handle, am I right? It seems like F# type inference system would not do anything more than what the C# does with var
typed variables.
You can define an inline
function with a member constraint, or go the classic route and use an interface (which would probably be preferred in this case).
let inline isOld (x:^T) = (^T : (member Age : int) x) >= 65
EDIT
I just remembered this won't work for record types. Technically their members are fields, although you can amend them with members using with member ...
. You would have to do that to satisfy an interface anyway.
For reference, here's how you would implement an interface with a record type:
type IAging =
abstract Age : int
type Dog =
{ DogName : string
Age : int }
interface IAging with
member this.Age = //could also be `this.Age = this.Age`
let { DogName = _; Age = age } = this
age
这篇关于F#和鸭子打字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!