我找到:
abs -10
abs -10L
Run Code Online (Sandbox Code Playgroud)
都工作.所以我想知道F#是如何实现这个并在源代码中进行搜索的:
type AbsDynamicImplTable<'T>() =
let AbsDynamic x = AbsDynamicImplTable<_>.Result x
[<CompiledName("Abs")>]
let inline abs (x: ^T) : ^T =
AbsDynamic x
when ^T : ^T = absImpl x
Run Code Online (Sandbox Code Playgroud)
我对这些感到困惑.
正如我所知,在函数中abs,我们必须将输入与0进行比较,并且对于不同的类型有不同的0.
谢谢.
我的问题与这个问题有些相关 - 具有通用参数类型的函数 - 但我无法弄清楚如何做我想要的事情.
我想定义一个'后代函数来包含对各种C#类的'Descendants'的调用,如下所示:
让后代名称(xDocument:XDocument)= xDocument.Descendants名称
让后代命名(xElement:XElement)= xElement.Descendants name
这种方法不起作用,因为我们有'后代'的重复定义.
我认为可以使用内联函数和静态解析参数来定义以下方法来代替:
let inline descendants name (xml : ^x when ^x : (member Descendants : XName -> seq<XElement>)) =
xml.Descendants name
Run Code Online (Sandbox Code Playgroud)
但是在尝试这样做时我遇到了这个错误:
根据此程序点之前的信息查找不确定类型的对象.在此程序点之前可能需要类型注释来约束对象的类型.这可以允许解析查找.
有没有办法可以写第二个功能来做我想做的事情?
我尝试以下方法:
let c x = System.Numerics.Complex(x, 0.0)
let sum = [c 1.0; c 2.0] |> List.sum
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:
The type 'System.Numerics.Complex' does not support the operator 'get_Zero'
我从https://msdn.microsoft.com/en-us/library/dd233211.aspx上阅读了类型扩展的规则,并尝试执行以下操作:
module ComplexExtension =
let c x = System.Numerics.Complex(x, 0.0)
type System.Numerics.Complex with
// I also tried a bunch of other ways of writing these
// as static or instance members, but nothing worked
static member Zero = c 0.0
static member One = c 1.0
open ComplexExtension
let sum = [c …Run Code Online (Sandbox Code Playgroud) 我已经定义了以下类型(从代码中简化):
type Polynomial<'a when 'a :(static member public Zero : 'a)
and 'a: (static member (+): 'a*'a -> 'a)
and 'a : (static member (*): 'a*'a -> 'a) > =
| Polynomial of 'a list
with
static member inline (+) (x: Polynomial<'a> , y : Polynomial<'a>) : Polynomial<'a>=
match x,y with
|Polynomial xlist, Polynomial ylist ->
let longer, shorter =
if xlist.Length> ylist.Length then xlist, ylist
else ylist, xlist
let shorterExtended = List.append shorter (List.init (longer.Length - shorter.Length) (fun _ …Run Code Online (Sandbox Code Playgroud) 通过Project Euler试图学习F#,我在为问题3编写解决方案时偶然发现了类似推断问题.
这是我写的:
let rec findLargestPrimeFactor p n =
if n = 1 then p
else
if n % p = 0 then findLargestPrimeFactor p (n/p)
else findLargestPrimeFactor (p+1) n
let result = findLargestPrimeFactor 2 600851475143L
Run Code Online (Sandbox Code Playgroud)
但是,编译器给出了以下错误:
error FS0001: This expression was expected to have type int but here has type int64
由于我希望从使用中findLargestPrimeFactor推断出使用的类型,我很惊讶地发现编译器似乎假设参数n是一个int,因为在函数的唯一调用是用int64完成的.
有人可以向我解释一下:
我刚刚学习F#,在tryfsharp.org上玩的时候,我注意到如果我更改了这段代码:
[0..100]
|> List.sum
Run Code Online (Sandbox Code Playgroud)
至
["A"; "B"; "D"]
|> List.sum
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
The type 'string' does not support the operator 'get_Zero'
Run Code Online (Sandbox Code Playgroud)
(这是你可以在你的浏览器中运行/修改的脚本,虽然它似乎只适用于我的IE!)
当我检查List.sum的定义时 ; 它说类型必须有一个名为Zero的静态成员.这似乎解释了错误; 除了我无法在int上看到任何名为Zero的成员!
所以; 这个适用于整数的零成员在哪里?如果我输入int.,我也无法在intellisense中看到它,也不会在docs中看到它,因为int只是一个.NET System.Int32(它似乎没有静态Zero属性).
(注意:它确实在错误中说"运算符"而不是"成员";这可能是相关的;虽然List.sum定义只是说"成员").
我希望能够使用静态方法从其他库扩展类型以启用泛型算法.以VectorN微软新推出的SIMD友好型固定尺寸类型为例.他们定义Zero,他们定义(+),他们定义(/),但我不能使用Array.average它们,因为他们没有定义DivideByInt,我很乐意:
open System.Numerics
type Vector2f with
static member DivideByInt (v:Vector2f) (i:int) = v / Vector2f(single i, single i)
let bigArray : Vector2f[] = readABigFile()
printf "the average is %A" (Array.average bigArray)
Run Code Online (Sandbox Code Playgroud)
但它不会让我编译,抱怨
error FS0001: The type 'Vector2f' does not support the operator 'DivideByInt'
Run Code Online (Sandbox Code Playgroud)
为什么F#编译器中存在此限制?
(编辑:基本上问过同样的问题.)
我是F#的新手.我在乱搞,我发现了一些有趣的东西,我希望有人可以告诉我幕后发生的事情.
所以我做了这个功能:let my_func (x, y) = x + y.
然后我用args调用了函数1并2给了我3.这是我期望发生的事情,但是当我传递两个字符串时,my_func我得到了一个错误,即使它+是一个有字符串的有效运算符.我重新我的代码,但这次只调用my_func与"cat"和" dog"它给了我"cat dog".然后我试图通过1和2回my_func才发现,my_func没有长期接受整数.
为什么my_func这样做?
let my_func (x, y) = x + y
my_func (1, 2) // produces => 3
my_func ("cat", " dog") // Error
重新运行程序 ......
let my_func (x, y) = x + y
my_func ("cat", " dog") // produces …
我有一个函数来计算序列的累积和.
let cumsum<'T> = Seq.scan (+) 0 >> Seq.skip 1 >> Seq.toArray
Run Code Online (Sandbox Code Playgroud)
虽然它看起来很通用,但整数0使它成为非泛型的,因此我不能用浮点序列调用该函数.
是否有一个通用的零可以替代我的硬编码0,或者可能是一种使函数通用的不同方式.
目前我们这样做......
let parseDate defaultVal text =
match DateTime.TryParse s with
| true, d -> d
| _ -> defaultVal
Run Code Online (Sandbox Code Playgroud)
是否有可能做到这一点...
let d : DateTime = tryParse DateTime.MinValue "2015.05.01"
Run Code Online (Sandbox Code Playgroud)