How to express this function point-free style in scala?

Imagine I have a simple key value datastore that provides me with a get and a set as defined by:

def set(key: String, value: String): String = ???
def get(key: String): String = ???
def switch(value: String): String = ???

I am trying to convert the following function to a composite point-free function:

def swichImportant(key: String): String = {
  val v = get(key)
  val newV = switch(v)
  set(key, newV)
}

I can do this:

val switchImportant2 = (k: String) => set(k, switch(get(k)))

Is it possible to express this function point-free style? The only option I can think about is to pass a case class around that has both the key and the value.

Upvotes: 1

Views: 359

Answers (1)

Joe K
Joe K

Reputation: 18424

The part that the Scala standard library is missing is essentially a function product:

def functionProduct[A, B, C]: (A => B, A => C) => A => (B, C) = ???

With that, you can do:

def switchImportant: String => String = {
  functionProduct(identity[String], (get _) andThen (switch _)) andThen (set(_, _)).tupled
}

But then you're stuck looking for a way to implement product point-free, even though it's obvious how to do it in regular scala style. If you really want to, you can involve cats, which has a Semigroupal typeclass that works with functions, so you could define it like:

def functionProduct[A, B, C]: (A => B, A => C) => A => (B, C) = {
  Semigroupal[({type F[Z] = A => Z})#F].product[B, C](_, _)
}

And then I guess you have done the whole thing point-free. But why? If you want point-free, you should probably be doing Haskell. Scala isn't really designed for it and nobody actually programs this way.

Upvotes: 2

Related Questions