F#模块中如何实现List.empty这类泛型值?
F# 泛型值实现原理说明
你遇到的问题本质是F#的值限制规则导致的:F#默认不允许无参数的非函数值自动泛型化,避免因副作用引发类型安全问题,所以你直接定义的无参数emptyFoo会被编译器固化为Foo<obj>类型,无法作为泛型值使用。
F#标准库中的List.empty这类无参数泛型值,是通过[<GeneralizableValue>]特性配合显式泛型声明实现的,你可以参考这种方式修改你的emptyFoo定义:
module Foo = [<GeneralizableValue>] let emptyFoo<'t> : Foo<'t> = { Foo = LanguagePrimitives.GenericZero<'t> }
这里有两个核心要点:
- 显式声明泛型参数
<'t>和返回类型Foo<'t>,明确告知编译器该值是泛型结构 - 添加
[<GeneralizableValue>]特性,向编译器证明该值是无副作用的纯值,泛型化不会引发类型安全问题,可以绕开值限制的约束
除此之外你也可以使用你最开始写的零参数函数(带()参数)的写法,函数类型不受值限制约束,天然支持泛型化,调用时添加()即可正常使用。
值限制规则的核心限制对象是无输入参数、可能存在副作用的计算值,函数类型和标记了可泛化特性的纯值不在限制范围内。
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

