0

だから私は、intリストからターゲット番号への有効な算術演算を見つける関数に取り組んでいます。throw/callac の使用は許可されていません。ここでは、add と mul のみが有効な算術演算であり、結合されたままになっています。

datatype operation = ADD | MULT

(* find_op: int -> int list -> (operatino list -> 'a) -> (unit -> 'a) -> 'a *)
fun find_op x [] s k = k()
  | find_op x [y] s k = if x=y then s([]) else k()
  | find_op x (y1::y2::ys) s k =
    let
      val add = find_op x ((y1+y2)::ys) (fn a => s(ADD::a)) k
      val mul = find_op x ((y1*y2)::ys) (fn a => s(MULT::a)) k
    in
      need some work here
    end

関数は以下のように動作するはずです:

リスト [1,1,2,~1] とターゲット番号 ~4 が与えられた場合、受け入れられる操作リストは [ADD,ADD,MULT] または [ADD,MULT,MULT] になります。 )*~1) = ((1+1) 2 ~1) = ~4. ただし、(((1*1)+2)*~​​1) = ~3 であるため、[MULT,ADD,MULT] は有効ではありません。

返された結果が k() かどうかを確認する方法がわかりません。= を使用して戻り値を確認することは、ポリモーフィックであるため不可能です。これを処理する方法はありますか?

4

1 に答える 1

1

あなたがしなければならないことは、2つの戦略を使用することです。最初に を介して数値をADD減らし、次に を介して数値を減らしますMULTが、順番に. これを行うkには、最初に選択した戦略の結果にカスタムの失敗継続 ( ) を提供する必要があります。その戦略が失敗した場合は、継続の失敗で 2 番目の戦略を試します。

両方の戦略を同時に試して、両方を成功させることはできません。関数型では、複数の正解を返すことはできません。そのためには、成功継続のタイプを にする必要がありますoperation list list

datatype operation = ADD | MULT

fun opToString ADD  = "ADD"
  | opToString MULT = "MULT"

(* find_op: int -> int list -> (operation list -> 'a) -> (unit -> 'a) -> 'a *)
fun find_op x [] s k               = k ()
  | find_op x [y] s k              = if x = y then s [] else k ()
  | find_op x (y1 :: y2 :: ys) s k =
    let
      (* You need a custom failure continuation that tries the MULT variant
       * if the ADD one fails.
       *)
      fun whenAddFails () =
        find_op x ((y1 * y2) :: ys) (fn a => s (MULT :: a)) k
      val add =
        find_op x ((y1 + y2) :: ys) (fn a => s (ADD :: a)) whenAddFails
    in
      add
    end


fun test () =
  let
    val opList = [1,1,2,~1]
    val target = ~4
    fun success ops =
      "success: " ^ (String.concatWith " " (List.map opToString ops))
    fun failure () =
      "couldn't parse numbers as an operation list"
  in
    find_op target opList success failure
  end
于 2015-02-23T17:12:34.260 に答える