【问题标题】:F# Option.flatten error with NoneF# Option.flatten 错误,无
【发布时间】:2018-04-04 09:54:00
【问题描述】:

在Option模块上应用flatten函数时出错:

let flatten  =
function
| None          -> None
| Some innerOpt -> innerOpt

这仅适用于以下输入:Some Some 1。 但如果输入是“无”,那么我会收到此错误:

flatten None 

error FS0030: Value restriction. The value 'it' has been inferred to have generic type
    val it : '_a option
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.

在 None 情况下,flatten 应该如何与泛型一起使用?

【问题讨论】:

    标签: f# options flatten


    【解决方案1】:

    flatten 是一个泛型函数,类型为'a option option -> 'a option。当参数为 None 时,编译器无法推断用于自动 REPL 变量 it(这是前一个表达式的结果)的类型参数。您可以指定自己的变量:

    let it : int option = flatten None;;
    

    明确指定None的类型:

    flatten (None : int option option);;
    

    flatten (Option<int option>.None);;
    

    或将泛型参数显式指定为flatten

    flatten<int> None;;
    

    这会生成一个警告,您可以通过将类型参数设置为 flatten 显式来删除它:

    let flatten<'a> (o : 'a option option) =
        match o with
        | None          -> None
        | Some innerOpt -> innerOpt
    

    【讨论】:

    • flattenOption (None : int option option) 是另一种明确指定参数类型的方法。查看blogs.msdn.microsoft.com/mulambda/2010/05/01/…了解更多详情。
    • 但是如果不指定它是通用的,它不应该工作吗?例如,在 Option.flatten 的情况下,我无法更改实现。所以我会得到同样的错误,除非我指定变量的类型: let result : int option 。为什么此实现不适用于 None。我知道这是因为它应该是通用的,但这是否意味着实现是错误的?它不应该与 None 一起工作,而不需要修改任何东西吗?我的意思是,如果它适用于 Some,它应该适用于 None,无需任何修改。
    • @FraK - 您对flatten 的定义是通用的,问题在于在提供None 作为参数时推断通用类型参数。在不需要您重新定义flatten 的答案中提供类型的方式有三种。返回值None在F#中不能有多态类型,所以你需要在参数类型或结果类型中指定它。
    • @Lee 但是Option&lt;int&gt;.None呢?
    • 这么多不错的选择(没有双关语)。感谢您的回复!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多