Skip to content

Instantly share code, notes, and snippets.

@sadache
Created August 17, 2010 13:44
Show Gist options
  • Save sadache/529983 to your computer and use it in GitHub Desktop.
Save sadache/529983 to your computer and use it in GitHub Desktop.
// I really do not like using the syntax that removes points
scala> List("one","two") foldLeft ("") (_+_)
<console>:6: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
List("one","two") foldLeft ("") (_+_)
^
// Int ???
scala> List("one","two") foldLeft ("") ((_+_):(String,String) => String)
<console>:6: error: type mismatch;
found : (String, String) => String
required: Int
List("one","two") foldLeft ("") ((_+_):(String,String) => String)
^
scala> List("one","two").foldLeft ("") (_+_)
res2: java.lang.String = onetwo
@deanwampler
Copy link

Is it a type inference limitation or just a case that the compiler didn't know that the (+) belonged with the foldLeft, since omitting the '.' is only supposed to work with zero or 1 argument methods? If so, then the error message wasn't very helpful as the real "error" was in deciding how to associate the parsed tokens.

@deanwampler
Copy link

Ah, you already commented on my suggestion...

@hedefalk
Copy link

I've been trying to get my head around the type inferer's behaviour around currying too. I got this from a Scheme-friend:

(reduce (lambda (x y) 
    (cons (if (null? y) 
    x 
    (+ x (car y))) y)) 
'(1 2 3) 
'())
=>
(6 5 3)

which I could translate to

 List(1, 2, 3).foldRight[List[Int]] (Nil) ((x, l) => if(l.isEmpty) List(x) else l.head + x :: l)

but I felt a bit ashamed for all the dots so as the ML fan boy I am I tried to remove them:

 scala> List(1, 2, 3) :\ (Nil : List[Int]) ((x,l) => if(l isEmpty) List(x) else (l head) + x :: l)  
 <console>:6: error: missing parameter type
       List(1, 2, 3) :\ (Nil : List[Int]) ((x,l) => if(l isEmpty) List(x) else (l head) + x :: l)
                                        ^

That error makes me want to add the parameter type to l and x in the anonymous function:

scala> List(1, 2, 3) :\ (Nil : List[Int]) ((x : Int, l : List[Int]) => if(l isEmpty) List(x) else (l head) + x :: l)
 <console>:6: error: type mismatch;
found   : (Int, scala.List[Int]) => scala.collection.immutable.List(in package immutable)[Int]
required: Int
       List(1, 2, 3) :\ (Nil : List[Int]) ((x : Int, l : List[Int]) => if(l isEmpty) List(x) else (l head) + x :: l)
                                                                ^

That obviously didn't work. It seems like the same error you got. In my example I at least mention Int so I didn't think more about it. But in your code Int is never even mention so that makes me think Int is just some kind of hacky last resort somewhere in the type inferer?

Anyway, I tried around a whole lot and finally I noticed that a parenthesis around the first function call did the trick just like in Mirkos example:

scala> (List(1, 2, 3) :\ (List[Int]())) ((x,l) => if(l isEmpty) List(x) else (l head) + x :: l)
 res5: List[Int] = List(6, 5, 3)

or maybe this one is the nicest:

 scala> (List(1, 2, 3) :\ (Nil : List[Int])) ((x,l) => if(l isEmpty) List(x) else (l head) + x :: l)
 res6: List[Int] = List(6, 5, 3)

Here I also typed Nil. The whole thing feels weird but I guess that the type inferer is doing really complex stuff. No simple Hindley–Milner here ;)

Mirko, did the underscores get lost somewhere? I need to do it like this:

scala> (List("one","two") foldLeft ("")) (_+_)
res8: java.lang.String = onetwo

I actually really LOVE point-free currying in ML but I guess the Scala one is somewhat limited and obviously makes the type inferer behave a bit weird sometimes.

@sadache
Copy link
Author

sadache commented Aug 18, 2010

I love ML currying, but this is not it and often it gets unpredictable to me. I guess there is a problem of precedence before the type inferencer kicks in. It is very confusing since it is hard to grasp even forgetting about this very case. I don't seem to be getting the mental model and that's why I tent to use it very rarely and only in places where it is clear and obvious.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment