【问题标题】:Define sum of square without defining parameter定义平方和而不定义参数
【发布时间】:2014-05-07 11:16:42
【问题描述】:

我想在没有明确使用参数的情况下定义sumOfSquares,而是依赖函数组合

下面是我的代码

let sumOfSquares = Seq.map (fun n -> n * n) >> Seq.sum

但是,我得到了以下错误

stdin(80,5):错误 FS0030:值限制。值“sumOfSquares” 已被推断为具有泛型类型

val sumOfSquares : ('_a -> int) when '_a :> seq<int> 

要么明确“sumOfSquares”的参数,要么,如果你不打算 它是通用的,添加一个类型注释。

解决它的一种方法是使用参数

let sumOfSquares nums = nums |> Seq.map (fun n -> n * n) |> Seq.sum

这将起作用。但是,我想看看我是否可以单独使用合成来定义平方和

更新

这是一个nice article 描述我遇到的问题:值限制。

【问题讨论】:

    标签: f# value-restriction


    【解决方案1】:

    让我们看看当类型推断在这里起作用时会发生什么。首先你有

    Seq.map (fun n -> n * n) >> Seq.sum
    

    现在Seq 允许任何实现Seq 的东西,我们可以输入int list int[] 或许多其他内容。

    结果,你得到 this 作为类型

    val sumOfSquares : ('_a -> int) when '_a :> seq<int> 
    

    现在的问题是sumofSquares 是一个值(它是一个函数)。不幸的是,您不能在顶级绑定中拥有通用值。但是,如果您明确说明参数,则可以使用通用函数。

    因此,类型注释的一种替代方法是使参数像这样显式

    let sumOfSquares s= s |> Seq.map (fun n -> n * n) |> Seq.sum
    

    这行得通

    在 SO 中搜索“值限制错误”应该会提供更多有关此问题的示例。

    【讨论】:

      【解决方案2】:

      做一个类型注解:

      let sumOfSquares : seq<int> -> int = 
          Seq.map (fun n -> n * n) >> Seq.sum
      

      【讨论】:

      • 谢谢。如果我错了,请纠正我,F# 假设我正在创建一个接受泛型类型参数的函数,但在类型推断时,它检测到我想定义 seq&lt;int&gt; -&gt; int,因此它变得“困惑”。是这样吗?
      • @OnesimusUnbound 正如您从消息中看到的那样,F# 推断您想要一个函数接受在类型层次结构中从IEnumerable&lt;int&gt; 下降的任何集合 并返回int。如果您希望参数严格为seq&lt;int&gt;,则必须对其进行注释:) 不幸的是,子类型化(以及重载)对于类型推断可能很棘手......
      猜你喜欢
      • 2021-08-05
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      相关资源
      最近更新 更多