I write a program to generate new color between a image, then i write a test below.
module Color = {
type t = (int, int, int, int) // r, g, b, a
let cmp = (c1: t, c2: t) => {
let (r1, g1, b1, _) = c1
let (r2, g2, b2, _) = c2
// only consider r,g,b
r1 === r2 && g1 === g2 && b1 === b2 ? 0 : -1
}
let toRgba = (color: t) => {
let (r, g, b, a) = color
`rgba(${r->Belt.Int.toString},${g->Belt.Int.toString},${b->Belt.Int.toString},${a->Belt.Int.toString})`
}
let to0x = (color: t) => {
let (r, g, b, _) = color
lsl(r, 16)->lor(_, lsl(g, 8))->lor(_, b)
}
}
module ColorId = Belt.Id.MakeComparable(Color)
let colorSet = Belt.MutableSet.make(~id=module(ColorId))
colorSet->Belt.MutableSet.add((0, 0, 0, 1))
colorSet->Belt.MutableSet.add((0, 0, 0, 1))
colorSet->Belt.MutableSet.add((0, 0, 0, 1))
colorSet->Belt.MutableSet.add((0, 0, 0, 2))
colorSet->Belt.MutableSet.add((0, 0, 0, 3))
colorSet->Belt.MutableSet.add((0, 0, 0, 4))
colorSet->Belt.MutableSet.add((0, 0, 0, 5))
colorSet->Belt.MutableSet.add((0, 0, 0, 6))
colorSet->Belt.MutableSet.add((0, 0, 1, 3))
Js.log2(`colorSet size: `, colorSet->Belt.MutableSet.size)
Js.log2(`colorSet to array: `, colorSet->Belt.MutableSet.toArray)
This program print:
The output is right, but when i add more color in colorSet, it behaves werid.
for _ in 0 to 270000 {
if Js.Math.random() > 0.5 {
colorSet->Belt.MutableSet.add((0, 0, 0, Js.Math.random_int(0, 256)))
} else {
colorSet->Belt.MutableSet.add((
Js.Math.random_int(0, 256),
Js.Math.random_int(0, 256),
Js.Math.random_int(0, 256),
Js.Math.random_int(0, 256),
))
}
}
Js.log2(`colorSet size: `, colorSet->Belt.MutableSet.size)
colorSet
->Belt.MutableSet.toArray
->Belt.Array.keep(item => {
let (r, g, b, _) = item
r === 0 && g === 0 && b === 0
})
->Belt.Array.slice(~offset=0, ~len=10)
->Js.log2(`the element equal to (0, 0, 0, _) is: `, _)
The output:
The colorSet should noly contains only one element which satisfies the condition r===0 && g===0 &&b===0. but it has a lot of element which satisfies this condition. Is it a bug, or just because i am not using Belt.MutableSet in the right way?