你如何在C#中做"内联函数"?我认为我不理解这个概念.他们喜欢匿名方法吗?像lambda函数?
注意:答案几乎完全处理内联函数的能力,即"用被调用者的主体替换函数调用站点的手动或编译器优化".如果您对匿名(也称为lambda)函数感兴趣,请参阅@ jalf的答案或者每个人都在说什么'Lambda'?.
在获取Array,List或Seq的第N个元素的函数中有不同的参数顺序是否有充分的理由:
Array.get source index
List .nth source index
Seq .nth index source
Run Code Online (Sandbox Code Playgroud)
我想使用管道运算符,它似乎只能用Seq:
s |> Seq.nth n
Run Code Online (Sandbox Code Playgroud)
有没有办法与Array或List使用相同的表示法?
我正在尝试学习F#中的静态成员约束.通过阅读Tomas Petricek的博客文章,我理解编写一个inline"仅使用自己使用静态成员约束编写的操作"的函数将使我的函数正确地适用于满足这些约束的所有数值类型.这个问题表明它的inline工作方式与c ++模板类似,所以我没想到这两个函数之间有任何性能差异:
let MultiplyTyped (A : double[,]) (B : double[,]) =
let rA, cA = (Array2D.length1 A) - 1, (Array2D.length2 A) - 1
let cB = (Array2D.length2 B) - 1
let C = Array2D.zeroCreate<double> (Array2D.length1 A) (Array2D.length2 B)
for i = 0 to rA do
for k = 0 to cA do
for j = 0 to cB do
C.[i,j] <- C.[i,j] + A.[i,k] * B.[k,j]
C
let inline MultiplyGeneric (A …Run Code Online (Sandbox Code Playgroud) 我在F#中有一个lisp风格语言的翻译,刚刚进入优化阶段.对评估者的简单测试表明,我需要以极端的方式对其进行优化.但是,我没有F#性能或优化的一般背景知识.
F#程序优化是否有任何良好的常识资源?特别有用的是保持缓存一致性和令人惊讶的原始性能问题的技巧.粗略的搜索在互联网上没有透露太多.
谢谢!
注意:我最后添加了很多Of interest评论.这些并不是在暗示一个人应该使用inline和static type parameters 威利愿意不愿意,他们有这么一个没有花时间搜索大量的SO与此相关的问题,以更好地理解这些概念的问题.
我知道当需要使函数通用并且需要零(0)值时,F#提供GenericZero.
解析为任何原始数字类型的零值或具有名为Zero的静态成员的任何类型.
所以这让我相信使用GenericZero字符串类型我只需要添加一个名为Zero的静态成员.
由于System.String是.Net框架的一部分,修改.Net源代码不是应该做的.但是,F#提供了Type Extensions.
类型扩展允许您将新成员添加到先前定义的对象类型.
此外,F#提供了String模块,但缺少GenericZero.
有关创建类型扩展的好教程,请参阅:将函数附加到类型.
我测试的代码:
这是在一个名为的项目中 Library1
namespace Extension.Test
module Extensions =
type System.String with
static member Something = "a"
static member StaticProp
with get() = "b"
static member Zero
with get() = "c"
Run Code Online (Sandbox Code Playgroud)
这是在一个名为的项目中 Workspace
namespace Extension.Test
module main =
open Extensions
[<EntryPoint>]
let main argv =
let stringSomething = System.String.Something
printfn …Run Code Online (Sandbox Code Playgroud) generics extension-methods f# type-inference generic-constraints
在F#中,我可以将字符串与+运算符组合如下:
let myString = "one" + "two"
Run Code Online (Sandbox Code Playgroud)
但是当我创建一个接受两个参数并应用相同运算符的函数时,我把它放在一个在其使用之前声明的模块中,F#将这些类型推断为整数:
module StringFunctions =
let add str1 str2 =
str1 + str2
Run Code Online (Sandbox Code Playgroud)
调用下面给出了构建错误,"表达式应该有'int'类型,但这里有'string'类型:"
let str3 = StringFunctions.add "three" "four"
为什么F#将其推断为int?我假设它不能是一个通用的方法,因为并非所有类型都会实现+运算符,但为什么它假设为int?
在F#中,为什么我的add函数不添加两个浮点数
let add a b = a+b
(add 3 4) //returns 7
(add 3.5 5.5) //error
Run Code Online (Sandbox Code Playgroud)
还请解释F#中的类型推断是如何工作的.
谢谢.
我仍然无法理解为什么我会将关键字inline用于函数.
它给了我什么,我还没有?
let inline (|Positive|Neutral|Negative|) x =
match sign x with
| 1 -> Positive
| -1 -> Negative
| _ -> Neutral
Run Code Online (Sandbox Code Playgroud) 最近有一些关于静态类型约束和内联的问题:
特别是两个陈述让我印象深刻:
"有没有办法来编码在.NET编译代码一流的方式这种类型的限制.然而,F#编译器可以在它内联函数,使所有运营商使用在编译时解析的现场强制执行这一约束".
"...但是F#也可以在编译的程序集之间内联,因为内联是通过.NET元数据传达的."
后者几乎似乎与前者相矛盾.我想知道为什么内联需要与静态类型约束功能相关.不能在F#编译器的工作方式(我相信)C++模板和泛型.NET做,并根据需要在编译时动态生成特定的类型,可重复使用的功能呢?
例如:
多态定义:
let add (lhs:^a) (rhs:^a) = lhs + rhs
Run Code Online (Sandbox Code Playgroud)
用法:
let a = add 2 3
let b = add 2. 3.
let b = add 4. 5.
Run Code Online (Sandbox Code Playgroud)
编译器生成的添加功能:
let add_int (lhs:int) (rhs:int) = lhs + rhs
let add_float (lhs:float) (rhs:float) = lhs + rhs
Run Code Online (Sandbox Code Playgroud)
编译器重写用法:
let a = add_int 2 3
let b = add_float 2. 3.
let c = add_float 4. 5.
Run Code Online (Sandbox Code Playgroud)
我不是编译器作家也不是语言设计师,虽然这些主题对我很感兴趣,所以请指出我的天真.
我需要创建一个函数,将两个由浮点数组成的元组相加,并返回一个由两个浮点数组成的元组。
let add a b =
fst a + fst b, snd a + snd b
Run Code Online (Sandbox Code Playgroud)
给我这个回报:
val add : int * int -> int * int -> int * int
Run Code Online (Sandbox Code Playgroud)
但如果我尝试:
let add (a:float) (b:float) =
fst a + fst b, snd a + snd b
Run Code Online (Sandbox Code Playgroud)
我明白了:
This expression was expected to have type
''a * 'd'
but here has type
'float'
Run Code Online (Sandbox Code Playgroud)
我该如何获得以下回报?
val add : float * float -> float * float -> float * float
Run Code Online (Sandbox Code Playgroud) f# ×9
generics ×2
inline ×2
optimization ×2
performance ×2
.net ×1
c# ×1
function ×1
pipeline ×1
tuples ×1