同じパターン変数による同値判定

各言語で試した結果は以下のとおり

Erlangの場合

できる

> case [1,1,1] of [X,X,X] -> "same"; _ -> "different" end. 
"same"
> case [1,1,2] of [X,X,X] -> "same"; _ -> "different" end.
"different"

Pureの場合

できる

> case [1,1,1] of [x,x,x] = "same"; _ = "different" end;
"same"
> case [1,1,2] of [x,x,x] = "same"; _ = "different" end;
"different"

Prologの場合

できる

?- [1,1,1] = [X,X,X], write(same); write(different).
same
X = 1.
?- [1,1,2] = [X,X,X], write(same); write(different).
different
true.

Haskellの場合

ガード(|)が必要

Prelude> case [1,1,1] of {[x,x,x] -> "same"; _ -> "different"}
    Conflicting definitions for `x'
    In a case alternative
Prelude> case [1,1,1] of {[x,y,z] | x==y && x==z -> "same"; _ -> "different"}
"same"
Prelude> case [1,1,2] of {[x,y,z] | x==y && x==z -> "same"; _ -> "different"}
"different"

OCamlの場合

ガード(when)が必要
なお(|)は他の言語での(;)と同じ

# match [1,1,1] with [x,x,x] -> "same" | _ -> "different";;
Error: Variable x is bound several times in this matching
# match [1,1,1] with [x,y,z] when x==y && x==z -> "same" | _ -> "different";;
- : string = "same"
# match [1,1,2] with [x,y,z] when x==y && x==z -> "same" | _ -> "different";;
- : string = "different"

Scalaの場合

ガード(if)が必要

scala> List(1,1,1) match {case List(x,x,x) => "same" case _ => "different"}
<console>:5: error: x is already defined as value x
scala> List(1,1,1) match {case List(x,y,z) if x==y && x==z > "same" case _ => "different"}
res: java.lang.String = same
scala> List(1,1,2) match {case List(x,y,z) if x==y && x==z > "same" case _ => "different"}
res: java.lang.String = different

Gauche(util.match)の場合

述語パターン(? ...)が必要だが、述語パターン中でxを参照できないのがつらい。
苦し紛れに(apply =)を使ったが、もっと複雑な構造とマッチさせるときは使えない。

gosh> (use util.match)
gosh> (match '(1 1 1) ((x y z) "same") (_ "different"))
*** ERROR: Compile Error: duplicate variable in pattern ((x x x) "same")
gosh> (match '(1 1 1) ((x (? (pa$ = x)) (? (pa$ = x))) "same") (_ "different"))
*** ERROR: unbound variable: x
gosh> (match '(1 1 1) ((? (pa$ apply =)) "same") (_ "different"))
"same"
gosh> (match '(1 1 2) ((? (pa$ apply =)) "same") (_ "different"))
"different"

追記
こういうときは失敗継続が使える

gosh> (match '(1 1 1) ((x y z) (=> k) (if (= x y z) "same" (k))) (_ "different"))
"same"
gosh> (match '(1 1 2) ((x y z) (=> k) (if (= x y z) "same" (k))) (_ "different"))
"different"

節が (pat (=> identifier) body …)の形式である場合、identifier は clause の失敗継続に束縛されます。これは引数をもたない手続きで、呼ばれると、あたかも、 pat の照合に失敗したかの如くマッチャーに戻り、match が残りの節について試行を続けます。それゆえ、body … 内部で追加のテストを実行することが可能で、もし、満足いくものでなければ、 (identifier) を呼ぶことで、照合結果を拒絶することができます。

http://practical-scheme.net/gauche/man/gauche-refj_164.html