Friday, January 16, 2009

A forward pipe (“ |> ”) operator in Scala

One of the addictive things from F# is the |> operator defined by

let |> a f = f a

but I've not yet found an equivalent in Scala, even though there are a ton of useful things given by the built-in APIs -- for example, I've not had to implement the usual abstraction to manage an (array, offset, length) combination, when there's Array.slice() there already.

So, just for fun...

package operator

object Functional {
    class PipedObject[T] private[Functional] (value:T)
        def |>[R] (f : T => R) = f(this.value)
    implicit def toPiped[T] (value:T) = new PipedObject[T](value)

with unit test

package operator
import junit.framework.TestCase
import junit.framework.Assert.assertEquals
import Functional._

class FunctionalTest extends TestCase {

    def sample(a : Any) = a.toString
    def test_|> () =
        assertEquals("the answer", "42", 6 * 7 |> sample)

    def makeFloating(a : Int) = a.toDouble

    def test_associating_|> () =
        assertEquals("the approximate answer", "42.0", 42 |> makeFloating |> sample)

Refrigerator logic — I later realise that without actually adding any variance annotations the piped-to function can be one that takes any super-class of the value type. A little more thought suggests to me that type-inference does that automagically because it is able to reconcile all inputs into the types in that single expression, and will force the value to the supertype in order to make everything match up.

Post a Comment