2016-08-04 42 views
6

Girdi alan bir girdim var ve ya başarılı olan ve bazı girdiler döndürür veya Hiçbiri döndürür. Biri numaralardan birini cevaplayana kadar aranan telefon numaralarının bir listesini vereceğim ve daha sonra sayıların geri kalanı atlanmalıdır. Ve sonunda başarılı bir sayı veya bir hata mesajının kaydı var. , TryPick Daha iyi bir Liste fonksiyonu ile o kadar sıkılırF # idiomatic Deneyi Başla

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 

: Bence

Benim ilk çözüm çok karmaşık ve aynı zamanda inelegant görünüyor ilk denemede, üzerinde arıza durumunun tohumlama kullanır

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 

Bu iyi bir yaklaşım gibi görünüyor mu? Monadik hataların ele alınışını okuduktan sonra, bu ruhda bir şekilde bir şeyler yapmam gerekip gerekmediğini merak ediyorum.

+4

'List.tryPick 'kullanarak çözümünüz tam olarak yazdığım kod gibi görünüyor ... –

+0

Teşekkürler Tomas. Cevabınızı takdir edin. – RomnieEE

+5

'List.tryPick' öğesine iletilen lambda, yalnızca' tryCallNumber' ile değiştirilebilir – TheQuickBrownFox

cevap

3

İdiomatisitenin ölçülmesi zordur. Bence yaklaşımın yakın-en-deyimsel.

Şahsen
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 

(maalesef olmayan: Ve Tomas' imzalamasını var ... Ben tryCallNumber lambda eta-azaltmak üzere, do damla, logCall için boruyu phoneNumbersfunction kısayol eklersiniz IMO option dönüş türleri yeterince açık ve benim kod try-ispirik olma eğilimindedir ve istisnalar bağlı değildir gibi, ayrıca , sadece için yeniden adlandırın. async -by varsayılan kitaplıklarına benzer şekilde ...Async son eki bırakılır.

+1

Ancak bir seçenek döndürmek için bir 'try' öneki saf işlevi için F # standart kütüphanesinde bir örnek var - örn. 'List.tryFind' - bir istisna atabilecek önekli olmayan bir karşı taraf olduğunda. Bu yüzden sık sık bu sözleşmeyi de takip ediyorum. Eminim, 'TryCallNumber' zaten çok uzun süre saf kalacak. Mevcut uygulama bir yer tutucu gibi görünüyor. – TheQuickBrownFox

+0

@TheQuickBrownFox Evet, kesinlikle. Daha net yapmalıydım, bu (şimdi) deyimsel değil. Umarım bu sonunda değişecektir :-) – CaringDev

+0

Yorumlar için teşekkürler. Bu çok kolaydı! (Ama ona ulaşmak için bir dolambaçlı rotaya bindim ...) Ama onu burada işaretçilerden biraz daha hassaslaştıracağım. Tekrar teşekkürler. – RomnieEE