2012-01-26 10 views
5

Jaki byłby F # idiomatyczny sposób pisania poniższych? Czy możesz zostawić to tak, jak jest?Czy ... inaczej .. idiomatyczny sposób pisania rzeczy w F #?

let input = 5 
let result = 
    if input > 0 && input < 5 then 
     let a = CalculateA(input) 
     let b = CalculateB(input) 
     (a+b)/2 
    else 
     CalculateC(input) 
+7

widzę w tym nic złego (choć mam zaprogramowany tylko w SML, nie F #) – fortran

+2

Absolutnie nic "unidiomatic" tutaj. – kkm

Odpowiedz

10

Na jednym if ... then ... else ... pewnie bym zostawić to tak, że jeśli miał więcej przypadków bym użyć wzoru mecz z kiedy strażnik:

let result = 
    match input with 
    | _ when input > 0 && input < 5 -> ... 
    | _ -> ... 

lub może także chcą wyglądać przy aktywnych wzorcach: http://msdn.microsoft.com/en-us/library/dd233248.aspx

0

To nie jest odpowiedź, ponieważ Robert ma rację. Ale wygląda na to, że pracujesz z szeregu funkcji, więc można napisać tak:

let Calculate input = 
    let calc = function | [f] -> f input | fl -> fl |> List.map ((|>) input) |> List.sum |> (fun s -> s/fl.Length) 
    if input > 0 && input < 5 
     then calc [CalculateA; CalculateB] 
     else calc [CalculateC] 

Można rozkładać na coś z tym podpisem: ((int -> int) list) -> ((int -> int) list) -> (int -> bool) -> int -> int a następnie budować swoją funkcję przez przyłożenie pierwsze 3 parametry.

+3

-1: WTF ?! To * ohydne *. –

+0

Cóż, tak jest :) Ale pierwotne pytanie wygląda tak: "jeśli wejście satifies to, następnie obliczyć średnią tych funkcji, w przeciwnym razie po prostu obliczyć tę funkcję". I właśnie znalazłem List.averageBy - cholera. – Huusom

+0

Doceniam sentyment, ale dlaczego nie '(jeśli input> 0 && input <5 to [A; B] else [C]) |> Seq.averageBy (fun f -> f input)' zamiast zbędnego specjalnego przypadku i transsyberyjski rurociąg zbędnych kombinatorów. :-) –

1

To drobne stylistyczne zmiany, ale uważam to bardziej czytelne:

let input = 5 
let result = 
    if input > 0 && input < 5 then 
     (calculateA input + calculateB input)/2 
    else 
     calculateC input 
2

Co byłoby F # idiomatyczne sposób pisania następujące? Czy możesz zostawić to tak, jak jest?

Nie ma nic złego w sposób, w jaki zostały napisane to, ale tu jest inna alternatywa (zainspirowany Huusom):

let input = 5 
let result = 
    if input>0 && input<5 then [A; B] else [C] 
    |> Seq.averageBy (fun f -> f input) 
+0

Tworzenie sekwencji dla średniej dwóch wartości może wydawać się przesadą, czyż nie? Czy to faktycznie stworzy .NET IEnumerable pod maską, czy kompilator zoptymalizuje to? –

+0

@AlexanderRautenberg: To może być przesada i na pewno będzie dużo wolniej. Chciałem po prostu zapewnić bardziej eleganckie rozwiązanie, idąc za przykładem Huusoma, że ​​oryginalny kod wyglądał, jakby miał do czynienia z dłuższymi sekwencjami. –

+0

uzyskanie go teraz, nie miał odpowiedniego kontekstu. W tym kontekście Twoje rozwiązanie wydaje się znacznie bardziej uzasadnione. :-) –

Powiązane problemy