ScalaFX is more or less 1:1 wrappers around corresponding JavaFX API, hence it would probably feel a bit Java-ish, and the JavaFX property/binding stuff is a bit clunky already. I’ve not used ScalaFX myself as I don’t think it’s quite the right approach, instead I’ve built my own library with minimal Scala-ish enhancements to key JavaFX APIs.
I’m not very familiar with Cats so I don’t quite see what you’re trying to do above, but you could get a long way with simple extention methods like this:
type Val[A] = ObservableValue[A]
extension [A] (v: Val[A])
def apply() = v.getValue
def map[B](f: A => B): Val[B] =
new ObjectBinding[B]:
bind(v)
def computeValue() = f(v.getValue)
extension [A1, A2] (v: (Val[A1], Val[A2]))
def mapN[B](f: (A1, A2) => B): Val[B] =
new ObjectBinding[B]:
bind(v._1, v._2)
def computeValue() = f(v._1.getValue, v._2.getValue)