什么/在哪里是get_Zero在F#的int? [英] What/where is get_Zero in F#'s int?

查看:133
本文介绍了什么/在哪里是get_Zero在F#的int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是在学习F#,而在 tryfsharp.org 玩游戏时,我注意到如果我更改此代码:

I'm just learning F#, and while playing at tryfsharp.org I noticed that if I change this code:

[0..100]
|> List.sum

["A"; "B"; "D"]
|> List.sum

我得到以下错误:

The type 'string' does not support the operator 'get_Zero'


$ b b

这是您可以在浏览器中执行/修改的脚本

当我检查 List.sum的定义;它说该类型必须有一个名为Zero的静态成员。这似乎解释了错误;除了我不能看到任何成员名为Zero on int!

When I checked the definition of List.sum; it says that the type must have a static member called Zero. This seems to explain the error; except for the fact that I can't see any member called Zero on int!

因此;这个零成员适用于ints在哪里?如果我输入 int。,也不能在文档,这说明int只是一个.NET System.Int32(似乎没有一个静态的Zero属性)。

So; where is this Zero member that applies to ints? I can't see it in intellisense if I type int., nor in the docs, which says int is just a .NET System.Int32 (which doesn't seem to have a static Zero property).

(注意: 运算符而不是成员的错误;这可能是相关的;虽然List.sum定义只是说成员)。

(note: it does say "Operator" and not "Member" in the error; which may be related; though the List.sum definition does just say "member").

推荐答案

搜索F#源代码,列表。 sum(和Seq.sum)使用GenericZero:

Digging in F# source code, List.sum (and Seq.sum) is using GenericZero:

let inline sum (source: seq< (^a) >) : ^a = 
    use e = source.GetEnumerator() 
    let mutable acc = LanguagePrimitives.GenericZero< (^a) >
    while e.MoveNext() do
        acc <- Checked.(+) acc e.Current
    acc

另一方面,F#编译器在查询零成员之前构建一个表以查找所有内置数值类型的零值。相关位位于此行中,

On the other hand, F# compiler builds a table to lookup zero values of all built-in numeric types before querying Zero members. The relevant bits are in this line and the code fragment below.

    type GenericZeroDynamicImplTable<'T>() = 
        static let result : 'T = 
            // The dynamic implementation
            let aty = typeof<'T>
            if   aty.Equals(typeof<sbyte>)      then unboxPrim<'T> (box 0y)
            elif aty.Equals(typeof<int16>)      then unboxPrim<'T> (box 0s)
            elif aty.Equals(typeof<int32>)      then unboxPrim<'T> (box 0)
            elif aty.Equals(typeof<int64>)      then unboxPrim<'T> (box 0L)
            elif aty.Equals(typeof<nativeint>)  then unboxPrim<'T> (box 0n)
            elif aty.Equals(typeof<byte>)       then unboxPrim<'T> (box 0uy)
            elif aty.Equals(typeof<uint16>)     then unboxPrim<'T> (box 0us)
            elif aty.Equals(typeof<uint32>)     then unboxPrim<'T> (box 0u)
            elif aty.Equals(typeof<uint64>)     then unboxPrim<'T> (box 0UL)
            elif aty.Equals(typeof<unativeint>) then unboxPrim<'T> (box 0un)
            elif aty.Equals(typeof<decimal>)    then unboxPrim<'T> (box 0M)
            elif aty.Equals(typeof<float>)      then unboxPrim<'T> (box 0.0)
            elif aty.Equals(typeof<float32>)    then unboxPrim<'T> (box 0.0f)
            else 
               let pinfo = aty.GetProperty("Zero")
               unboxPrim<'T> (pinfo.GetValue(null,null))
        static member Result : 'T = result

也就是说,如果你想在用户定义的类型上使用 List.sum ,你需要明确定义零成员。注意, Zero 在字符串类型的情况下没有多大意义。

That said, if you would like to use List.sum on user-defined types, you need to define Zero member explicitly. Note that Zero doesn't make much sense in case of string type.

这篇关于什么/在哪里是get_Zero在F#的int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆