2

些細なことのように思えますが、私の脳は私を失敗させているので、これを尋ねることさえ愚かです。私が以下を持っていた場合:

let a, b, c = 1, 1, 1

a、b、およびcがすべて同じ値を保持しているかどうかを判断するための適切な方法はありますか。何かのようなもの:

let result = (a = b = c)

a = b式がtrueを返し、次の式が結果としてtrue = cboolではなくintを期待していると文句を言うため、これは失敗します。私が考えることができる唯一のことは:

a = b && a = c && b = c

変数を追加したい場合は機能しません。

本当に私がやろうとしているのはこれです:

let same (x: string * string * string) =
    match x with
    | (a, a, a) -> true
    | _ -> false

すべての要素を1つの要素に一致させ、それらが異なる場合は先に進むことを望んでいましたが、一致の2番目の要素にはすでにバインドされていると表示されます。

4

4 に答える 4

8

リスト内のすべての値が同じであるかどうかを確認するには:

let rec same = function
  | x::y::_ when x <> y -> false
  | _::xs -> same xs
  | [] -> true

使用法

let a, b, c = 1, 1, 1
same [a; b; c] //true
于 2012-07-13T20:38:33.070 に答える
2
let same (a, b, c) = a = b && b = c
于 2012-07-13T20:11:31.893 に答える
2

すべての数値が同じであるかどうかを判断するために、forall関数を使用しようとします。

let list = [a; b; c;];;
List.forall (fun n -> n = a) list;;
val it : bool = true
于 2012-07-15T08:34:18.947 に答える
2

このソリューションは、まさに必要な構文を生成します。驚いたことに、かなり速いです。また、これは、計算式としても知られるモナドを使用する良い例のようです。

// Generic
let inline mOp1<'a> op sample x = op sample x, sample
let inline mOp2<'a> op1 op2 (b, sample) x = op1 b (op2 sample x), sample

// Implementation for (=) and (&&)
let (==) = mOp1 (=)
let (&=) = mOp2 (&&) (=)

// Use
let ret1 = a == b &= c &= d &= e |> fst

使い方

このアプローチは、非常に単純化された州のモナドです。モナディックタイプはのタプルです(bool, 'T)。最初の要素は進行中の計算のブール値であり、2番目の要素は比較するサンプル値です。

(==)演算子と同様に、モナドを初期化しますDelay
(&=)以降のすべての比較に使用されます。演算子に似ていBindます。かなりうまく機能するので、
必要ありません。とは論理演算の抽象化です。これらにより、独自の演算子を定義できます。との例を次に示します。Returnfst
mOp1mOp2or-equaland-greater-than

let (|=) = mOp2 (||) (=)
let (.>) = mOp1 (>)
let (&>) = mOp2 (&&) (>)
// Use
let ret2 = a == b |= c |= d |= e |> fst // if any of b,c,d,e equals to a
let ret3 = 5 .> 3 &> 4 |> fst // true: 5>3 && 5>4
let ret4 = 5 .> 3 &> 8 &> 4 |> fst // false

パフォーマンス

@ildjarnによる美しいソリューションを本当に楽しんでいましたが、構築Listが非常に遅いため、私の主な目標はパフォーマンスでした。
8回の比較のチェーンを実行し、1,000万回:

  • 04972msa=b && a=с && ...
  • 23138msListベース
  • 12367msモナディック
于 2012-07-19T00:40:21.957 に答える