Análisis de argumentos de línea de comandos -- f# camp codereview Relacionados El problema

Parsing command line arguments


3
vote

problema

Español

Uso:


  // Usage: dndgenerate /e [emhd] [0-9+] //          dndgenerate /e d 4 4 5 4 // /e   Generate Encounter. Parameter can be one of //          e - Easy //          m - Medium //          h - Hard //          d - Deadly //      As well as a list of heroes by their levels // // Example:  dndgenerate /e m 4 4 5 4 //      Generate a medium encounter for three level 4 and one level 5 adventurers.   

El código para que esto suceda:


  type DifficultyOption = Easy | Medium | Hard | Deadly  type EncounterOptions = {     difficulty: DifficultyOption option     heroes: int list }  let (|Level|_|) (str: string) =     let mutable intValue = 0      if System.Int32.TryParse(str, &intValue)         then match intValue with              | x when x < 0 -> None              | x when x > 20 -> None              | x -> Some x         else None    let (|Difficulty|_|) (str: string) =     match str with     | "e" | "E" -> Some(Easy)     | "m" | "M" -> Some(Medium)     | "h" | "H" -> Some(Hard)     | "d" | "D" -> Some(Deadly)     | x -> None  let isComplete (options:EncounterOptions) =     not <| options.heroes.IsEmpty && options.difficulty.IsSome  type VerboseOption = VerboseOutput | TerseOutput  type MiscOptions = {     verbose: VerboseOption }  type GeneratorType =     | E of EncounterOptions     | Unknown  type ParseMode = TopLevel | Encounter | Plot | Dungeon | Settlement | Error  type CommandLineOptions = {     misc: MiscOptions     parseMode: ParseMode     generatorType: GeneratorType }  let parseTopLevel arg miscSoFar =     match arg with     | "/v" ->         let newMiscSoFar = { miscSoFar with verbose = VerboseOutput }         { misc = newMiscSoFar; parseMode = TopLevel; generatorType = Unknown }      | "/e" ->          { misc = miscSoFar; parseMode = Encounter; generatorType = E { difficulty = None; heroes = [] } }      | x ->         { misc = miscSoFar; parseMode = Error; generatorType = Unknown }  let parseEncounter arg miscSoFar encounterGenerator =     match arg with     | Level x ->         let builder' = { encounterGenerator with heroes = x :: encounterGenerator.heroes }         { misc = miscSoFar; parseMode = Encounter; generatorType = E builder' }      | Difficulty x ->         let builder' = { encounterGenerator with difficulty = Some x }         { misc = miscSoFar; parseMode = Encounter; generatorType = E builder' }      | _ ->          { misc = miscSoFar; parseMode = Error; generatorType = E encounterGenerator }  let foldFunction state element =     match state with     | { misc = m; parseMode = TopLevel } ->         parseTopLevel element m      | { misc = m; parseMode = Encounter; generatorType = E(g) } ->         parseEncounter element m g      | { parseMode = Error } ->         state      | { misc = m; parseMode = p; generatorType = g } ->          printfn "Unexpected constellation of %A %A %A" m p g         state  let disableIfIncomplete commandLineOptions =     match commandLineOptions.parseMode with     | Error ->         commandLineOptions      | _ ->         match commandLineOptions.generatorType with         | E(encounter) when isComplete encounter ->             commandLineOptions          | Unknown -> commandLineOptions          | _ -> { commandLineOptions with parseMode = Error }  let parseCommandLine args =     let defaultOptions = {          verbose = TerseOutput     }      let initialFoldState =         { misc = defaultOptions; parseMode = TopLevel; generatorType = Unknown }      let finalFoldState = args |> List.fold foldFunction initialFoldState      disableIfIncomplete finalFoldState   

Basado en el código de Scott WlaSchin's analizando los argumentos de la línea de comandos pero extendido Para incluir grupos de argumentos y manejo de errores. Avanzado a propósito FPARSEC porque soy nuevo en # y quería resolverlo primero en el estilo de vainilla.

Original en ingles

Usage:


// Usage: dndgenerate /e [emhd] [0-9+] //          dndgenerate /e d 4 4 5 4 // /e   Generate Encounter. Parameter can be one of //          e - Easy //          m - Medium //          h - Hard //          d - Deadly //      As well as a list of heroes by their levels // // Example:  dndgenerate /e m 4 4 5 4 //      Generate a medium encounter for three level 4 and one level 5 adventurers. 

The code to make it happen:


type DifficultyOption = Easy | Medium | Hard | Deadly  type EncounterOptions = {     difficulty: DifficultyOption option     heroes: int list }  let (|Level|_|) (str: string) =     let mutable intValue = 0      if System.Int32.TryParse(str, &intValue)         then match intValue with              | x when x < 0 -> None              | x when x > 20 -> None              | x -> Some x         else None    let (|Difficulty|_|) (str: string) =     match str with     | "e" | "E" -> Some(Easy)     | "m" | "M" -> Some(Medium)     | "h" | "H" -> Some(Hard)     | "d" | "D" -> Some(Deadly)     | x -> None  let isComplete (options:EncounterOptions) =     not <| options.heroes.IsEmpty && options.difficulty.IsSome  type VerboseOption = VerboseOutput | TerseOutput  type MiscOptions = {     verbose: VerboseOption }  type GeneratorType =     | E of EncounterOptions     | Unknown  type ParseMode = TopLevel | Encounter | Plot | Dungeon | Settlement | Error  type CommandLineOptions = {     misc: MiscOptions     parseMode: ParseMode     generatorType: GeneratorType }  let parseTopLevel arg miscSoFar =     match arg with     | "/v" ->         let newMiscSoFar = { miscSoFar with verbose = VerboseOutput }         { misc = newMiscSoFar; parseMode = TopLevel; generatorType = Unknown }      | "/e" ->          { misc = miscSoFar; parseMode = Encounter; generatorType = E { difficulty = None; heroes = [] } }      | x ->         { misc = miscSoFar; parseMode = Error; generatorType = Unknown }  let parseEncounter arg miscSoFar encounterGenerator =     match arg with     | Level x ->         let builder' = { encounterGenerator with heroes = x :: encounterGenerator.heroes }         { misc = miscSoFar; parseMode = Encounter; generatorType = E builder' }      | Difficulty x ->         let builder' = { encounterGenerator with difficulty = Some x }         { misc = miscSoFar; parseMode = Encounter; generatorType = E builder' }      | _ ->          { misc = miscSoFar; parseMode = Error; generatorType = E encounterGenerator }  let foldFunction state element =     match state with     | { misc = m; parseMode = TopLevel } ->         parseTopLevel element m      | { misc = m; parseMode = Encounter; generatorType = E(g) } ->         parseEncounter element m g      | { parseMode = Error } ->         state      | { misc = m; parseMode = p; generatorType = g } ->          printfn "Unexpected constellation of %A %A %A" m p g         state  let disableIfIncomplete commandLineOptions =     match commandLineOptions.parseMode with     | Error ->         commandLineOptions      | _ ->         match commandLineOptions.generatorType with         | E(encounter) when isComplete encounter ->             commandLineOptions          | Unknown -> commandLineOptions          | _ -> { commandLineOptions with parseMode = Error }  let parseCommandLine args =     let defaultOptions = {          verbose = TerseOutput     }      let initialFoldState =         { misc = defaultOptions; parseMode = TopLevel; generatorType = Unknown }      let finalFoldState = args |> List.fold foldFunction initialFoldState      disableIfIncomplete finalFoldState 

Based on code from Scott Wlaschin's Parsing command line arguments but extended to include argument groups and error handling. Purposefully avoided FParsec because I'm new to F# and wanted to solve it vanilla-style first.

  

Lista de respuestas

1
 
vote

También soy nuevo en #, así que tengo solo 2 pequeñas anotaciones:

La función que analiza la cadena a INT32 se puede simplificar:

  y0  

El último caso de la función y1 debe ser y2 en lugar de y3 porque el valor no se usa ('_' expresa exactamente eso )

 

I am also new to F#, so I have just 2 small annotations:

The function that parses the string to Int32 can be simplified:

match System.Int32.TryParse(str) with     | (true, x) when x >= 0 && x <= 20 -> Some x     | _ -> None 

The last case of the function parseTopLevel should be _ -> instead of x -> because the value is not used ('_' expresses exactly that)

 
 

Relacionados problema

10  Obteniendo la última fecha donde ocurrió un día de la semana dado  ( Getting the last date where a given week day occurred ) 
Estoy tratando de aprender un poco sobre la programación funcional y como mi herramienta, elegí F # ya que soy un desarrollador de .NET y el medio ambiente es...

4  ¿Cómo refactorizar este método de Groupby por igual pero con el índice?  ( How to refactor this groupby alike method but with index ) 
Tengo una matriz jaggada 2D (la fila es la primera dimensión, la columna es la segunda dimensión, la parte inferior de la derecha, de izquierda a derecha) ...

4  Clases de datos puros inmutables con artículos públicos en propiedades  ( Immutable pure data classes with public setters on properties ) 
Estoy reuniendo algunas clases como modelo para alguna información (que actualmente estoy tirando de un sitio web). Las clases se implementan en C #, porque...

3  Convertir el valor de bitcoin basado en el tipo de cambio de JSON API  ( Convert bitcoin value based on exchange rate from json api ) 
Estoy aprendiendo F # e intentando encontrar una forma más 'funcional' de codificar un programa simple que recupera el precio de BTC y calcula el valor del EU...

3  Mi implementación de permutación lexicográfica en F # es 3x más lenta que C #  ( My implementation of lexicographic permutation in f is 3x slower than c ) 
¿Puede alguien ayudarme con la siguiente micro optimización para el código F # para la permutación lexicográfica? Tengo código en C # que se ejecuta para 0,...

2  F # Patrón activo con póquer y naipes  ( F active pattern with poker and playing cards ) 
de Esta pregunta y John Palmers responden Sobre el patrón activo Descubrí una brecha en mi conocimiento sobre F # y tomé el desafío de codificarme en algún ...

9  Eliminación de árbol negro rojo en F #  ( Deleting from red black tree in f ) 
Sí, estoy muy lentamente a través de las estructuras de datos puramente funcionales. Así que pasé por la sección sobre árboles negros rojos. Lo que presenta e...

2  Usando tipos en F #  ( Using types in f ) 
He jugado con F # por más de un año, pero recientemente he comenzado tentativamente lo usándolo para el trabajo profesional. Me preocupa que mis principios de...

11  Enfoque para construir programáticamente componentes gui jerárquicos  ( Approach to programmatically building hierarchical gui components ) 
En el trabajo, estoy desarrollando una aplicación usando el swing codificado a mano, y he encontrado que tengo un tiempo más fácil de leer, escribir y mantene...

13  Poker Hands Kata en F #  ( Poker hands kata in f ) 
Soy un F # Newbie, y me gustaría compartir mi implementación de la Poker Hands Kata Problem Para obtener algunos comentarios. string1 En la primera mi...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos