2016-08-04 7 views
6

私は、入力を受け取り、成功し、返す関数をいくつか持っています。この例では、誰かが数字のいずれかに答えるまでダイヤルされる電話番号のリストを作成し、残りの数字はスキップする必要があります。最後に、成功した番号またはエラーメッセージのログが記録されます。私が思うF#idiomatic Try Until

私の最初のソリューションは、洗練思われる、あまりにも複雑であり、また、最初の試行で障害状態の播種を使用しています。

type PhoneNumber = int 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let nextCall phoneNumberOption nextNumber = 
    match phoneNumberOption with 
    | Some num -> phoneNumberOption 
    | None  -> tryCallNumber nextNumber 

let logCall phoneNumberOption = 
    match phoneNumberOption with 
    | Some num -> printfn "%i" num 
    | None  -> printfn "%s" "failed" 


let phoneNumbers = [111; 222; 444; 555] 

do List.fold (fun state num -> (nextCall state num)) None phoneNumbers 
|> logCall 

私はより良いリスト機能、tryPickでそれを締め:

type PhoneNumber = int 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let logCall phoneNumberOption = 
    match phoneNumberOption with 
    | Some num -> printfn "%i" num 
    | None  -> printfn "%s" "failed" 


let phoneNumbers = [111; 222; 444; 555] 

do List.tryPick (fun num -> tryCallNumber num) phoneNumbers 
|> logCall 

これは良いアプローチのようですか?モナドのエラー処理について読んだ後、私は何とかその精神の中で何かをやっていなければならないのだろうかと思います。

+4

'List.tryPick'を使ったあなたのソリューションは、私が書いたコードとまったく同じように見えます... –

+0

Thanks Tomas。あなたの返事を感謝します。 – RomnieEE

+5

'List.tryPick'に渡されたラムダは、' tryCallNumber'だけで置き換えることができます。 – TheQuickBrownFox

答えて

3

偶然性を測定することは困難です。私は、あなたのアプローチが、最も近似的なものであると考えています。そして、あなたはトマスサインオフを持っている...私は、logCallためfunctionショートカットを追加doを落とし、パイプphoneNumberstryCallNumberラムダイータ減少するであろう:

let phoneNumbers = [111; 222; 444; 555] 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let logCall = function 
| Some num -> printfn "%i" num 
| None  -> printfn "failed" 

phoneNumbers 
|> List.tryPick tryCallNumber 
|> logCall 

個人的に(残念ながら非IM/option戻り値の型が十分明確で、コードがtry - 重く、例外に依存しない傾向があるので、tryCallNumberの名前をcallNumberに変更します。 async-...Asyncという接尾辞が削除された既定のライブラリです。

+1

しかし、F#標準ライブラリには、オプションを返すための 'try'接頭辞の純粋な関数の前例があります。 'List.tryFind' - 例外をスローする可能性のあるプレフィックスのない対応がある場合ですから、私はしばしばその大会に従います。とにかく 'tryCallNumber'がとにかく純粋なままであるかどうか分かりません。現在の実装はプレースホルダのようです。 – TheQuickBrownFox

+0

@TheQuickBrownFoxはい、絶対に。私は、これが慣用的ではないということをもっと明確にすべきだった(今)。うまくいけば、これは最終的に変更されます:-) – CaringDev

+0

コメントありがとうございます。これは簡単すぎました! (しかし、私はそれに到達するために迂回ルートを取った...)しかし、私はここでポインタから少しでも洗練されます。再度、感謝します。 – RomnieEE