F# 和鸭子类型
假设我在 F# 中定义了以下两种类型:
type Dog = { DogName:string; Age:int }
type Cat = { CatName:string; Age:int }
我期望以下方法适用于猫和狗:
let isOld x = x.Age >= 65
实际上,似乎发生的情况是 isOld
只接受猫:
let dog = { DogName = "Jackie"; Age = 4 }
let cat = { CatName = "Micky"; Age = 80 }
let isDogOld = isOld dog //error
我的希望是F# 足够聪明,可以为猫和狗定义某种“虚拟”接口 X
,以便 isOld
接受 X 作为参数,而不是 猫
。
这不是 F# 在任何情况下都会处理的事情,对吗?看起来 F# 类型推断系统不会比 C# 对 var
类型变量执行更多操作。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以定义带有成员约束的内联函数,或者采用经典路线并使用接口(在这种情况下可能是首选)。
编辑
我只是记得这不适用于记录类型。从技术上讲,它们的成员是字段,尽管您可以使用
with member ...
使用成员来修改它们。无论如何,你都必须这样做才能满足接口的要求。作为参考,以下是如何实现具有记录类型的接口:
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).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:
通常,F# 鸭子类型意味着编译时多态性。语法有点奇怪,但您应该能够从以下示例中算出它 -
请记住,这种多态性仅在编译时有效!
Usually what is meant by F# duck-typing is a compile-time polymorphism. Syntax is a little weirder, but you should be able to work it out from the following example -
Remember, this polymorphism only works at compile-time!
FSharp.Interop.Dynamic(在 nuget 上)提供了基于 DLR 的实现动态运算符(真正的动态鸭子类型)
FSharp.Interop.Dynamic (on nuget) provides a DLR based implementation of the dynamic operator (real dynamic duck typing)