小编Rus*_*tam的帖子

魔术sprintf功能 - 如何包装?

我正在尝试包含对sprintf函数的调用.这是我的尝试:

let p format args = "That was: " + (sprintf format args)

let a = "a"
let b = "b"

let z1 = p "A %s has invalid b" a 
Run Code Online (Sandbox Code Playgroud)

这似乎工作,输出是

val p : format:Printf.StringFormat<('a -> string)> -> args:'a -> string
val a : string = "a"
val b : string = "b"
val z1 : string = "That was: A a has invalid b"
Run Code Online (Sandbox Code Playgroud)

但它不适用于多个arg:

let z2 = p "A %s has invalid b %A" a …
Run Code Online (Sandbox Code Playgroud)

f#

4
推荐指数
1
解决办法
332
查看次数

区分联合方法不会看到其静态成员

问题似乎很愚蠢,但我真的不明白.

module Responses =
    type Failure = 
        | Problem of string 
        | Error of exn 
        | Timeout
        static member toString x = 
            match x with
            | Problem str -> sprintf "Problem %s" str
            | Error e -> sprintf "Error %s" (e.ToString())
            | Timeout -> "Timeout"
        override x.ToString() = Failure.toString x 
Run Code Online (Sandbox Code Playgroud)

错误是

      override x.ToString() = Failure.toString x;;
--------------------------------------^^^^^^^^
stdin(11,41): error FS0039: The field, constructor or member 'toString' is not defined
Run Code Online (Sandbox Code Playgroud)

原因是f#因某种原因认为Failure属于类型Microsoft.FSharp.Core.Operations.Failure

当我试着写

override x.ToString() = Responses.Failure.toString x
Run Code Online (Sandbox Code Playgroud)

我明白了 …

f# static discriminated-union

4
推荐指数
1
解决办法
545
查看次数

在声明之前使用变量/函数

我有一个无法解决的递归:

module Test
type Command = 
    | Exit of string
    | Action of string * (unit -> unit)

let getName command = 
    match command with
    | Exit(n) -> n
    | Action(n, _) -> n

let listCommands commands = 
    List.iter (getName >> printf "%s\n") commands

let hello () = 
    printf "Well, hi\n"

let help () = 
    printf "Available commands are:\n"
    listCommands commands // <- ERROR IS HERE!!!, F# doesn't know of commands array

let commands = [
    Exit("exit")
    Action("hello", hello)
    Action("help", …
Run Code Online (Sandbox Code Playgroud)

f#

3
推荐指数
1
解决办法
211
查看次数

构造值初始化

我从F#开始,我无法理解构造值初始化的最佳方法是什么:

let x = TryCalculateX() // for example, searching in DB
if x = null then
    // for example, we create it ourself and out it into DB
    let x = TryAnotherCalcultaion() 
    someProcessing x // x is now initialized => Ok
someProcessing x // here I use old, not initialized x! => Fails
Run Code Online (Sandbox Code Playgroud)

你如何处理类似的情况?

UPD.我设计的最好的是:

let getX() =
    let res = TryCalculateX() 
    if res = null then
        let res = TryAnotherCalcultaion() 
        res
    else
        res
Run Code Online (Sandbox Code Playgroud)

这不是很酷,恕我直言

Upd 2. @ChaosPandion提出了很好的解决方案:

let x …
Run Code Online (Sandbox Code Playgroud)

f#

3
推荐指数
1
解决办法
131
查看次数

如何使f#查询表达式可重用?

我试图习惯f#查询表达式.

首先,他们绝对渴望,因为:

let arr = [1; 2; 3]
let q = query { for item in arr do select item; count };;

val arr : int list = [1; 2; 3]
val q : int = 3
Run Code Online (Sandbox Code Playgroud)

我想重用该查询,所以我尝试延迟计算:

let arr = ref [1; 2; 3]
let q = lazy query { for item in !arr do select item; count }
q.Value;;

val arr : int list ref = {contents = [1; 2; 3];}
val q : Lazy<int> = 3
val …
Run Code Online (Sandbox Code Playgroud)

linq f# lazy-evaluation computation-expression

1
推荐指数
1
解决办法
153
查看次数