我希望能够
let upcast'<'T,'TResult when 'T :> 'TResult> (y:'T) = y |> upcast
但是,这样会将'T
约束为'TResult
,而不是将其强制转换为'TResult
我知道我可以
|> fun x -> x :> 'TResult
|> fun x -> upcast x
|> fun x -> x :> _
,但是如果我在那行上还有其他事情要做,我必须回过头来将()
放在fun x -> upcast x
周围,否则它会认为我正在做的事情是{{1}的一部分}功能。
我可以定义还是存在一种方法来
fun x
不起作用
|> upcast |>
不起作用,而且混乱
编辑 作为对Thomas Petricek的回应-最少失败的自动上传示例:
|> ( ( :> ) 'TResult)
答案 0 :(得分:5)
据我所知,不可能指定'T
和'TResult
之间的约束类型。有一个相关的question about this,其中包含指向更多信息和功能请求的链接。
那是说,我不知道你为什么需要这个? F#编译器即使在使用管道时也能够自动插入上流,因此,如果您希望将其作为较长管道的一部分来执行,则不需要。这是一个简单的例子:
type Animal = interface end
type Dog = inherit Animal
let makeDog () = { new Dog }
let consumeAnimal (a:Animal) = 0
makeDog () |> consumeAnimal
我想,如果您想在管道的末尾进行管道传输,可能需要管道传输,但是我只是在另一行进行传输。还是您的问题是由一些更复杂的情况引起的,其中隐含的上行链路不起作用?
编辑1:这是一个使用ReadOnlyCollection
和IReadOnlyList
的最小示例,该示例有效:
let foo () : System.Collections.ObjectModel.ReadOnlyCollection<int> = failwith "!"
let bar (x:System.Collections.Generic.IReadOnlyList<int>) = 0
foo() |> bar
编辑2:要对更新进行评论-这里的问题是,仅在将参数传递给函数时才插入自动上播,但是在第二个示例中,类型不匹配是在结果之间管道和函数的返回类型。您可以通过在管道末尾添加IReadOnlyCollection<'T> -> IReadOnlyCollection<'T>
类型的标识函数来使其工作:
let inline f<'t> () :IReadOnlyCollection<'t> =
List.empty
|> ResizeArray
|> System.Collections.ObjectModel.ReadOnlyCollection
|> id<IReadOnlyCollection<_>>
之所以可行,是因为现在将参数传递给id
函数时会自动插入upcast,然后返回与该函数的返回类型匹配的类型。
答案 1 :(得分:0)
更加简单和意外
let inline f2<'t>() : IReadOnlyCollection<'t> =
List.empty
|> ResizeArray
|> System.Collections.ObjectModel.ReadOnlyCollection
:> _