1

次のコードを書きたい:

let someAsync () = async {
    if 1 > 2 then return true // Error "this expression is expected to have type unit ..."
    // I want to place much code here    
    return false
}

F# は何らかの理由で、次のように記述する必要があると考えています。

let someAsync () = async {
    if 1 > 2 then return true
    else
        // Much code here (indented!)
        return false
}

後者の場合、エラー メッセージは生成されません。しかし、私の見解では、両方のコードは同等です。不必要な入れ子やインデントを回避できる可能性はありますか?

アップデート。私が求めていることは確かに可能です!を見てください。実世界の例のセクションを参照してください。

コードを引用します:

let validateName(arg:string) = imperative {
    if (arg = null) then return false  // <- HERE IT IS
    let idx = arg.IndexOf(" ")
    if (idx = -1) then return false    // <- HERE IT IS

    // ......
    return true 
}

したがって、可能です。唯一の問題は、asyncモジュールへの拡張などを介して、何らかの形で実装できるかどうかです。

4

2 に答える 2

2

async計算ビルダーと私のビルダーの間には重要な違いがありimperativeます。

ではasync、値を返さない有用な計算を作成することはできません。これは、Async<'T>が最終的に type の値を生成する計算を表すことを意味します'T。この場合、async.Zeroメソッドは返す必要unitがあり、署名があります。

async.Zero : unit -> Async<unit>

imperiatveビルダーの場合、型はImperative<'T>値を返す場合と返さない場合がある計算を表します。型宣言を見ると、次のようになります。

type Imperative<'T> = unit -> option<'T>

これは、操作 (なしZeroで記述するときに使用される) が任意のタイプの計算になる可能性があることを意味します。したがって、メソッドは任意のタイプの計算を返します。ifelseimperative.Zero

imperative.Zero : unit -> Imperative<'T>

これは基本的な違いであり、分岐ifなしで作成できる理由も説明しています(メソッドは任意のタイプの計算を作成できるため)。は を返す値しか作成できないため、これは不可能です。elseZeroasyncZerounit

したがって、2 つの計算の構造は異なります。特に、「命令型」計算にはモノイド構造があり、非同期ワークフローにはありません。詳細については、F# Computation Zoo ペーパーで説明を見つけることができます。

于 2014-04-07T14:28:48.800 に答える