阅读Array2D模块的源代码,我在许多核心函数的实现中偶然发现了这个有趣的结构,例如:
[<CompiledName("Get")>]
let get (array: 'T[,]) (n:int) (m:int) = (# "ldelem.multi 2 !0" type ('T) array n m : 'T #)
Run Code Online (Sandbox Code Playgroud)
我只能假设这是内联CIL的语法,这里使用它显然是为了获得性能优势.但是,当我尝试在程序中使用此语法时,出现错误:
warning FS0042: This construct is deprecated: it is only for use in the F# library
Run Code Online (Sandbox Code Playgroud)
究竟是什么?有没有详细的文件?
考虑这个界面:
type A<'a> =
abstract X : 'a
Run Code Online (Sandbox Code Playgroud)
让我们尝试用它int作为通用参数来实现它:
{ new A<int> with member this.X = 5 } // all is well
Run Code Online (Sandbox Code Playgroud)
现在,让我们尝试unit一个论点:
// Compiler error: The member 'get_X : unit -> unit' does not have the correct type to override the corresponding abstract method.
{ new A<unit> with member this.X = () }
Run Code Online (Sandbox Code Playgroud)
现在,如果我们定义一个非泛型接口,一切都运行良好:
type A_int =
abstract X : int
{ new A_int with member this.X = 5 } // works
type A_unit = …Run Code Online (Sandbox Code Playgroud) C#编译器非常智能,可以优化字符串与+运算符串联到String.Concat调用中.
以下代码:
var a = "one";
var b = "two";
var c = "three";
var d = "four";
var x = a + b + c + d;
Run Code Online (Sandbox Code Playgroud)
编译成这个IL:
IL_0000: ldstr "one"
IL_0005: stloc.0 // a
IL_0006: ldstr "two"
IL_000B: stloc.1 // b
IL_000C: ldstr "three"
IL_0011: stloc.2 // c
IL_0012: ldstr "four"
IL_0017: stloc.3 // d
IL_0018: ldloc.0 // a
IL_0019: ldloc.1 // b
IL_001A: ldloc.2 // c
IL_001B: ldloc.3 // d
IL_001C: call System.String.Concat …Run Code Online (Sandbox Code Playgroud) 我正在尝试定义一个宏来定义Clojure 1.3中添加的编译时常量语法:
== 2.14 ^:const defs ==
^:const允许您使用更快的引用命名原始值.
(def常数{:pi 3.14:e 2.71})
(def ^:const pi(:pi constants))(def ^:const e(:e constants))
查找的开销:e和:地图中的pi发生在编译时,因为(:pi常量)和(:e常量)在评估其父def形式时进行评估.
基本上我想要一些语法糖(def ^:const ... ...),所以我试着这样做:
(defmacro defconst [const-name const-val]
`(def ^:const ~const-name ~const-val))
Run Code Online (Sandbox Code Playgroud)
但这不起作用:
user=> (macroexpand '(defconst pi 3.14))
(def pi 3.14)
Run Code Online (Sandbox Code Playgroud)
从我收集的#^<...>元快捷方式是一个读取器宏,并定义一个宏添加一些元数据的东西,人们应该使用(with-meta ...).
我没有找到任何关于的文件^:const.这个语法结构是否甚至可以创建某种元数据?以下示例未显示任何内容:
user=> (def ^:const pi 3.14)
#'user/pi
user=> (meta pi)
nil
Run Code Online (Sandbox Code Playgroud) 我正在编写异步HTTP API客户端模块/库.为了使所有内容尽可能干,我试图从进行API调用的单独部分组成每个HTTP API调用,自下而上:构建请求,获取响应,将响应读入字符串缓冲区,解析JSON内容那个字符串缓冲区成一个对象.
到目前为止,我有这个代码:
module ApiUtils =
// ... request builder fns omitted ...
let getResponse<'a> (request : Net.WebRequest) =
request.AsyncGetResponse()
let readResponse (response : Net.WebResponse) =
use reader = new StreamReader(response.GetResponseStream())
reader.AsyncReadToEnd()
let getString = getResponse >> (Async.flatMap readResponse)
let parseJson<'T> responseText : 'T =
Json.JsonConvert.DeserializeObject<'T> responseText
let getJson<'T> = getString >> (Async.map parseJson<'T>)
Run Code Online (Sandbox Code Playgroud)
而且,正如您所看到的,我已经使用我自己的附加功能扩展了Async模块:
module Async =
let map f m =
async {
let! v = m
return f v
}
let flatMap f m =
async …Run Code Online (Sandbox Code Playgroud) .net f# asynchronous functional-programming computation-expression
我需要调用一个返回一些我不需要的值的函数.通常情况下,我只是管道ignore.但是如果返回的值是IDisposable什么呢?
ignore操作员是否负责处理传递的参数?从它的源代码,看起来不是:
[<CompiledName("Ignore")>]
let inline ignore _ = ()
Run Code Online (Sandbox Code Playgroud)
所以为了这个目的,use __ = someFunc ()我使用这个函数而不是写作:
let inline dispose (x : #IDisposable) = x.Dispose()
// usage example
someFunc () |> dispose
Run Code Online (Sandbox Code Playgroud)
我想知道,这是正确的方法,或者可能已经有这样的内置运营商?或者只是使用它会ignore好吗?
我在F#中定义了这两个函数
let f t =
match t with
|_ when t = 0 -> 1
|_ -> g t-1
let g t = 1 + (f t)
Run Code Online (Sandbox Code Playgroud)
但是,F#编译器不接受它.它说
stdin(9,16): error FS0039: The value or constructor 'f' is not defined
Run Code Online (Sandbox Code Playgroud)
请帮我!谢谢.
只是为了练习,我试图找到一种用Python列表理解来表达Pascal三角形的方法,并以迭代的方式做到这一点.我用Python代表Pascal的三角形:
tri = [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], ...]
Run Code Online (Sandbox Code Playgroud)
当我正在迭代地进行时,我需要以某种方式访问先前计算的三角形线,并且我试图在不声明局部变量的情况下执行此操作.
到目前为止我有这个:
tri = [lines.append(
([1] + [lines[i][j]+lines[i][j-1] for j in xrange(1, i+1)] + [1]) if i > 0
else [1, 1])
or lines[i] for i, lines in enumerate([[[1]]]*height)]
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
编辑:正如@brc所指出的,这是如何和/或何时使用列表推导的非常糟糕的例子.