我甚至对这个问题感到愚蠢,因为它看起来很琐碎,但是我的大脑让我失望了。如果我有以下内容:
let a, b, c = 1, 1, 1
是否有一种方法可以确定a,b和c是否都保持相同的值。类似的东西:
let result = (a = b = c)
这失败是因为表达式a = b
返回true而下一个表达式导致true = c
并抱怨它期望int,而不是bool。我唯一能想到的是:
a = b && a = c && b = c
当我想添加更多变量时,它将无效。
我真正想做的是:
let same (x: string * string * string) =
match x with
| (a, a, a) -> true
| _ -> false
我希望我可以将所有元素匹配到一个元素中,如果它们不同,它会继续前进,但它会在匹配中的第二个元素上说它已被绑定。
答案 0 :(得分: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
答案 1 :(得分:2)
let same (a, b, c) = a = b && b = c
答案 2 :(得分:2)
我会尝试使用forall函数来确定所有数字是否相同。
let list = [a; b; c;];;
List.forall (fun n -> n = a) list;;
val it : bool = true
答案 3 :(得分:2)
此解决方案可生成所需的语法。令我惊讶的是,相当快。此外,似乎是使用monad的一个很好的例子,也称为Computation Expressions。
// 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
该方法是一个非常简化的 State monad 。 monadic类型是(bool, 'T)
的元组。第一个组件是正在进行的计算的布尔值,第二个组件是要与之比较的样本值。
(==)
会初始化monad,类似于Delay
运算符
(&=)
用于所有后续比较。它类似于Bind
运算符
我们不需要Return
,因为fst
会很好用。{
mOp1
和mOp2
是逻辑运算的抽象。这些允许定义自己的运算符。以下是or-equal
和and-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个比较链,1000万次:
a=b && a=с && ...
List
- 基于