myList |> List.filter (fun item ->
if item.MyValue < 10 then
sideEffect ()
true
else
false )
Run Code Online (Sandbox Code Playgroud)
如果我设置断点false ),则会被忽略/跳过.
我必须:
false
)
Run Code Online (Sandbox Code Playgroud)
我并不是很想知道为什么会这样(很容易做出有根据的猜测),就像知道这是否会被解决一样.
目前,我正在使用Daniel Mohl的"F#Web应用程序(Silverlight)"扩展来完全使用F#(Visual Studio 2010)创建Silverlight应用程序.
我需要做本地文件I/O(这显然需要提升信任度),我也想在浏览器外运行应用程序,但我无法以正常方式设置它(例如正如我在Daniel Mohl的"F#C#Web App(Silverlight)"扩展中所做的那样,因为全F#配置中的项目设置不提供必要的设置.
我可以通过在文本编辑器中对项目文件进行一些简单的修改来设置它,还是涉及更多步骤?
在http://diditwith.net上,我看到,在F#中,并不是必须将参数传递给否则需要它们的函数.该语言将自动将结果和输出参数填充到元组中.(!)
这是语言的一般机制的某种副作用(请原谅双关语),还是F#规范中特别明确表达并故意编程到语言中的特征?
这是一个很棒的功能,如果它被明确地放入F#中,那么我想知道这种语言中潜藏的其他金块是什么,因为我已经浏览了几十个网页并阅读了三本书(由D Syme,T.Petricek和C. Smith)我根本没有看到这个特别的提法.
编辑:正如Petricek先生在下面回答的那样,他确实在他的书" 真实世界功能编程"中至少提到了两个地方.我的错.
为什么在F#中,我可以这样做......
let s = seq { for i in 0 .. 4095 do yield i } :?> IEnumerator
Run Code Online (Sandbox Code Playgroud)
......但这会抛出一个System.InvalidCastException?
let s = Seq.init 4095 (fun i -> i) :?> IEnumerator
Run Code Online (Sandbox Code Playgroud) 在Visual Studio 2015中:
let myFunction (``string`` : string) =
"\"Quoted string\"" |> (Regex "\"[^\"]*\"").Match |> string
let myOtherFunction (str : string) =
"\"Quoted string\"" |> (Regex "\"[^\"]*\"").Match |> string
Run Code Online (Sandbox Code Playgroud)
第一个函数生成编译器错误,该string函数以红色下划线.("这个表达式预计会有类型匹配 - >'a但这里有类型字符串")
第二个功能很好,没问题.
这是设计的吗?
这里没问题:
module Seq =
let private rnd = Random Environment.TickCount
let random =
fun (items : 'T seq) ->
let count = Seq.length items
items |> Seq.nth (rnd.Next count)
Run Code Online (Sandbox Code Playgroud)
签名Seq.random是items:seq<'T> -> 'T.都好.
是的,我知道我可以let random items = [...],这不是重点.
关键是当我这样做时items突然被限制为类型seq<obj>:
module Seq =
let random =
let rnd = Random Environment.TickCount
fun (items : 'T seq) ->
let count = Seq.length items
items |> Seq.nth (rnd.Next count)
Run Code Online (Sandbox Code Playgroud)
...即我将Random对象添加为闭包.如果我将鼠标悬停在上面random,Intellisense会告诉我签名已经变成了 …
我认为我已经对F#monads(工作流)有了足够的了解,我在代码中看到了一些实现它们的地方.
例如,我有一个具有多个嵌套if/thens的函数,即只要数据通过某些"测试",函数就应该继续.
我熟悉"也许"monad,但在我看过的所有例子中,它都被编码为对let!绑定进行操作,我没有这样做.我希望有人可以为我提供一个为嵌套布尔测试量身定制的"可能"工作流程的示例,而不是let绑定.
我的风格:
open System
type MyType (myFn : unit -> bool) =
member this.MyResult with get () = myFn ()
new (myFn : Func<bool>) = MyType (myFn.Invoke)
Run Code Online (Sandbox Code Playgroud)
我得到的错误:
A unique overload for method 'MyType' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : myFn:(unit -> bool) -> MyType, new : myFn:Func<bool> -> MyType
既然我已经提供了类型注释,那么这个不起作用的真正原因是什么?
> type XList<'T> (_collection : seq<'T>) =
inherit List<'T> (_collection)
member this.Add _item = if not <| this.Contains _item then base.Add _item
new () = XList<'T> (Seq.empty<'T>);;
inherit List<'T> (_collection)
--------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(47,9): error FS0945: Cannot inherit a sealed type
Run Code Online (Sandbox Code Playgroud)
我的理解是List <'T>实际上没有密封.没有?
此外,这似乎在F#interactive之外工作得很好.确切的代码在我的F#项目中,编译器处理它而不抱怨.我在几个C#项目中也有同样的事情.代码在每种情况下都按预期工作.
通常,我只是使用静态方法扩展List <'T>(将其作为"F#方式"),但隐藏List.Add也应该正常工作.
鉴于以下内容:
type IFruit = interface end
type Avocado = { color : string; age : int } interface IFruit
let (|AvocadoTexture|) (a : Avocado) = if a.age < 7 then "firm" else "mushy"
Run Code Online (Sandbox Code Playgroud)
...为什么这样做:
let texture (f : IFruit) =
match f with
| :? Avocado as a -> if a.age < 7 then "firm" else "mushy"
| _ -> String.Empty
Run Code Online (Sandbox Code Playgroud)
......但不是吗?
let texture (fruit : IFruit) =
match fruit with
| AvocadoTexture t -> t // "The type IFruit …Run Code Online (Sandbox Code Playgroud) 我更喜欢为F#以惯用方式将函数与类型分开:
[<Struct>]
type Vec2 =
{
x : single
y : single
}
static member inline (/) (v, scalar) =
let s = single scalar in { x = v.x / s; y = v.y / s }
[<CompilationRepresentation (CompilationRepresentationFlags.ModuleSuffix)>]
module Vec2 =
let inline length v = ((pown v.x 2) + (pown v.y 2)) |> sqrt
let unit v = let l = length v in { x = v.x / l; y = v.y / l }
Run Code Online (Sandbox Code Playgroud)
不幸的是,在C#中, …
假设不会对以下类型进行进一步的修改或添加,那么这种方式与另一种方式相比是否有任何优势(除了第二个示例的较少打字和更好的可读性和效率)?
type MyType<'T> (_initVal : 'T) =
let getSetFns () =
let value = ref _initVal
(fun () -> value.Value), (fun _value -> value := _value)
let getVal, setVal = getSetFns ()
member this.Value with get () = getVal () and set _value = setVal _value
Run Code Online (Sandbox Code Playgroud)
... 要么...
type MyType<'T> (_initVal : 'T) =
let value = ref _initVal
member this.Value with get () = value.Value and set _value = value := _value
Run Code Online (Sandbox Code Playgroud) 鉴于let ra = ResizeArray<int> ():
Seq.forall (fun i ->
let q = i % 2
if 0 = q then ra.Add i
true ) <| seq { 1..10 }
Run Code Online (Sandbox Code Playgroud)
如果我这样做,ra.Count退货5.
Seq.forall (fun i ->
let q = i % 2
if 0 = q then ra.Add i
0 = q ) <| seq { 1..10 }
Run Code Online (Sandbox Code Playgroud)
如果我这样做,ra.Count退货0.
那么,除非lambda函数的每次迭代求值为true,否则实际上函数中没有任何代码被执行,或者什么?
这里发生了什么?
f# ×13
c# ×2
closures ×2
seq ×2
backticks ×1
breakpoints ×1
constructor ×1
dictionary ×1
ienumerator ×1
interactive ×1
interop ×1
list ×1
maybe ×1
module ×1
monads ×1
overloading ×1
scope ×1
sealed ×1
silverlight ×1
tuples ×1