2015-08-08 2 views
2

Я пишу функцию в f #, которая может быть выполнена с несколькими блоками if/else, но читает намного более чистую с предложением match/with. Проблема в том, что во многих случаях меня не волнует, что переменная фактически сопоставляется; Вместо этого я использую «когда».f #: Использование «match/with» block sans the «with»

Вопрос в том, есть ли способ выполнить «матч/с», используя только «когда» блоки и не имеет реальной переменной соответствия?

let primes (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
     match input' with 
     | _ when input' = 1I -> acc 
     | _ when input = factor -> factor::acc 
     | _ when input' = factor -> factor::acc 
     | _ when input' % factor = 0I -> factor::factors acc (input'/factor, factor) 
     | _ -> factors acc (input', factor+1I) 
    in factors [] (input, 2I) 

primes 1I |> List.iter (printf "%A "); printfn "..";  
primes 12I |> List.iter (printf "%A "); printfn ".."; 
primes 60I |> List.iter (printf "%A "); printfn ".."; 
primes 420I |> List.iter (printf "%A "); printfn ".."; 
primes 1260I |> List.iter (printf "%A "); printfn ".."; 
primes 13I |> List.iter (printf "%A "); printfn ".."; 

[Править] Было высказано предположение, что это тот же самый вопрос, как this, и я полагаю, что это. Но если бы не этот пост, я бы не видел ответа Карстен, и именно этого я и думал. Теперь, когда я знаю, я предполагаю, что эти два варианта являются

let primes (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
     match() with 
     |() when input' = 1I   -> acc 
     |() when input = factor  -> factor::acc 
     |() when input' = factor  -> factor::acc 
     |() when input' % factor = 0I -> factor::factors acc (input'/factor, factor) 
     | _ -> factors acc (input', factor+1I) 
    in factors [] (input, 2I) 

let primes' (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
     if input' = 1I   then acc 
     elif input = factor   then factor::acc 
     elif input' = factor  then factor::acc 
     elif input' % factor = 0I then factor::factors acc (input'/factor, factor) 
     else factors acc (input', factor+1I) 
    in factors [] (input, 2I) 

Видя их бок о бок, как это оставляет меня с мнением, что я должен использовать Элиф-х.

+0

Возможный дубликат [F # multi-condition if/else против соответствия] (http://stackoverflow.com/questions/31877649/f-multi-condition-if-else-versus-matching) –

ответ

1

Ну вы могли бы использовать активные-шаблоны, но я думаю, что это слишком много накладных расходов в этом случае здесь, если нет - вы не можете избежать where здесь (или, по крайней мере, я не курсе любого пути).

Существует шаблон, который сделает это немного более очевидным (что вы не заботитесь о стоимости согласованной только о when статей):

match() with 
|() when ... -> ... 
|() when ... -> ... 
| _ -> ... 

вы могли видеть.

2

Условия, указанные здесь, относятся к различным входам, поэтому их не так много. Это ситуация, когда цепочки if/else более кратки. Вы можете, однако, использовать немного короткий elif ключевого слова:

let primes (input:bigint) = 
    let rec factors acc (input':bigint, factor:bigint) = 
     if input' = 1I then acc 
     elif input = factor then factor::acc 
     elif input' = factor then factor::acc 
     elif input' % factor = 0I then factor::factors acc (input'/factor, factor) 
     else factors acc (input', factor+1I) 
    in factors [] (input, 2I) 

соответствия шаблона является ценным, когда у вас есть единственного входа, который может иметь различные различные ароматы или форму, но в этом случае вам достаточно иметь различные разные входы, где взаимосвязь между ними определяет ветвление, иерархически.

Смежные вопросы