1

私は F# で単純な式パーサーを作成しています。各演算子について、特定の数のオペランドのみをサポートしたいと考えています (たとえば、Modulo の場合は 2 つ、If の場合は 3 つ)。ここに私が持っているものがあります:

type Operator =
    | Modulo
    | Equals
    | If

let processOperator operands operator =
    match operator with
    | Modulo ->
        match operands with
        | [ a:string; b:string ] -> (Convert.ToInt32(a) % Convert.ToInt32(b)).ToString()
        | _ -> failwith "wrong number of operands"
    | Equals ->
        match operands with
        | [ a; b ] -> (a = b).ToString()
        | _ -> failwith "wrong operands"
    | If ->
        match operands with 
        | [ a; b; c ] -> (if Convert.ToBoolean(a) then b else c).ToString()
        | _ -> failwith "wrong operands"

内部リストの一致を取り除くか、単純化したいと思います。これを達成するための最良の方法は何ですか?複数のガードを使用する必要がありますか?

4

2 に答える 2

4
open System

type Operator =
    | Modulo
    | Equals
    | If

let processOperator operands operator =
    match (operator, operands) with
    | Modulo, [a: string; b] -> string ((int a) % (int b))
    | Equals, [a; b] -> string (a = b)
    | If, [a; b; c]  -> if Convert.ToBoolean(a) then b else c
    | _ -> failwith "wrong number of operands"

しかし、オペランドのこのロジックをパーサーに移動することをお勧めします。このようにして、より慣用的で処理が簡単なクリーンな演算子式が得られます。最終的には、次のようになります。

open System

type Operator =
    | Modulo of int * int
    | Equals of int * int
    | If of bool * string * string

let processOperator = function
    | Modulo (a, b) -> string (a % b)
    | Equals (a, b) -> string (a = b)
    | If (a, b, c)  -> if a then b else c
于 2014-03-16T19:03:47.363 に答える
3

一致するオペランドを折りたたみます。

let processOperator operands operator =
    match operator, operands with
    | Modulo, [a; b] -> (Convert.ToInt32(a) % Convert.ToInt32(b)).ToString()
    | Equals, [a; b] -> (a = b).ToString()
    | If, [ a; b; c ] -> (if Convert.ToBoolean(a) then b else c).ToString()
    | _ -> failwith "wrong number of operands"

できれば、データ型を次のように変更してください。

type Operator =
    | Modulo of string * string
    | Equals of string * string
    | If of string * string * string

そうすれば、試合で失敗することはもうありません。

于 2014-03-16T18:57:25.053 に答える