当我期望具有不同泛型参数实例化的相同接口时,如何推断函数的参数类型?

问题描述 投票:0回答:1

以下代码片段无法编译:

[<Interface>]
type IEnvironment<'T> =
    abstract Service: 'T
type IStringEnvironment = IEnvironment<string>
type IIntEnvironment = IEnvironment<int>

module StringEnvironment =

    let get (env: #IStringEnvironment) = env.Service

module IntEnvironment =

    let get (env: #IIntEnvironment) = env.Service

module Composition =

    let get env = 
        let a = StringEnvironment.get env
        let b = IntEnvironment.get env
        a,b 

我想知道为什么?

我的代码中的设置几乎相同,只是我不使用 IEnvironment 接口,但对于不同的上下文,我有不同的“环境”,例如我有以下内容:

type ILoggerEnvironment =
    abstract GetLogger: ILogger

[<Interface>]
type IDateTimeEnvironment =
    abstract GetCurrent: DateTime

然后这个组合似乎起作用了。

我尝试了不同的解决方案,将所有函数编写为内联函数,但编译器期望 env 的第一次使用的类型为该类型(即使在参数类型之前添加了 #)。

f# refactoring type-inference f#-compiler-services
1个回答
0
投票
module Composition =

  let get env = 
    let a = StringEnvironment.get env
    let b = IntEnvironment.get env
    a,b 

env
的实例只能是
IEnvironment<string>
IEnvironment<int>
,不能同时是两者。

因为我不知道你的最终目标是什么,所以我无法给出建议,但通常如果你想使用不同类型的底层价值观,你可以将它们与受歧视联盟(DU)统一起来,如下所示:

type Env =
  | Str of IEnvironment<string>
  | Int of IEnvironment<int>

仍然是

Env
的实例只能是
Str
Int
,因此您尝试做的构图不成立。

© www.soinside.com 2019 - 2024. All rights reserved.