Search code examples
scalatuplesarity

Why does my implementation of Haskell snd not compile in Scala?


I defined the following function along the lines of Haskell snd

def snd[T](pair: (_, T)): T = pair._2

Trying to use it with a List[ListNode[T]] doesn't compile. Why not?

list
  .reduceOption(snd)

where:

case class ListNode[T](data: T, var next: Option[ListNode[T]])(implicit ordering: Ordering[T]) extends Ordered[ListNode[T]] {...}

Error:

Type mismatch, expected: (NonInferedA1, NonInferedA1) => NonInferedA1, actual Tuple2[_, Nothing] => Nothing

Solution

  • Methods reduce and reduceOption require functions with arity 2, not unary functions that take a tuple.

    There is a difference between

    Function1[(X, Y), Z]
    

    and

    Function2[X, Y, Z]
    

    The first one is unary and takes a tuple, the second one is binary. Same holds for methods and their eta-expansions.

    This here works as expected:

    def twoArgSnd[T](a: Any, b: T): T = b 
    
    list.reduceOption(twoArgSnd[Int])
    

    Also related:

    1. Why is scala.collection.immutable.List[Object] not GenTraversableOnce[?]