This turns out to be quite a bit simpler than I initially expected.
This turns out to be quite a bit simpler than I initially expected. First we need to define a simple HList, sealed trait HList final case class HConsH, T Out, Out { def apply(l : H :: HNil, f : H => Out) = f(l. Head) } // Case for HLists of length n+1 implicit def foldCurry2H, T FT, Out { def apply(l : H :: T, f : H => FT) = fct(l.
Tail, f(l. Head)) } // Public interface ... implemented in terms of type class and instances above def foldCurryL i+j+k+l val f1c = f1. Curried val l1 = 1 :: 2 :: 3 :: 4 :: HNil // In the REPL ... note the inferred result type scala> foldCurry(l1, f1c) res0: Int = 10 And we can also use the same unmodified foldCurry for functions with different arity's and non-uniform argument types, val f2 = (i : Int, s : String, d : Double) => (i+1, s.
Length, d*2) val f2c = f2. Curried val l2 = 23 :: "foo" :: 2.0 :: HNil // In the REPL ... again, note the inferred result type scala> foldCurry(l2, f2c) res1: (Int, Int, Double) = (24,3,4.0).
Your function expects exactly 4 Int arguments. FoldLeft is a function that applies to an arbitrary number of elements. You mention List(1,2,3,4) but what if you have List(1,2,3,4,5) or List()?List.
FoldLeftB also expects a function to return the same type B, but in your case Int and some Function1Int, _ is not the same type. Whatever solution you come up with would not be general either. For instance what if your function is of type (Int, Float, Int, String) => Int?
You would then need a ListAny So it's definitely not a job for List.foldLeft. With that in mind (warning very un-scala code): class AccT(f: Function1T, _) { privatethis var ff: Any = f def apply(t: T): this. Type = { ff = ff.
AsInstanceOfFunction1T,_(t) this } def get = ff match { case _: Function1_,_ => sys. Error("not enough arguments") case res => res. AsInstanceOfT } } List(1,2,3,4).
FoldLeft(new Acc(f. Curried))((acc, i) => acc(i)). Get // res10: Int = 10.
Thank you, @huynjl. I've clarified my question to state that I'm looking for an answer that doesn't modify my original expression except for adding a type for g, but this certainly gets the job done. Regarding the lack of generality and the limitations of List.
FoldLeft -- can we define some "fold-like thing" (to use Sabin's phrase) that works just as well on tuples? – Adam Pingel Oct 1 at 17:23 I've been thinking about the 4-ness of my particular example. While it's true that infinitely long type signatures are not possible (that I know of) in Scala, and that the usual use of foldLeft is rarely if ever limited by the zero, it's exactly that quality of this example that makes it interesting.
I can imagine many contrived but valid situations where the zero or the operator halt execution before the input is consumed, but this is a case that's actually interesting and useful (imho). – Adam Pingel Oct 3 at 2:39 @AdamPingel, without bring infinite lists in the picture, it was an interesting problem already without an obvious solution. I think the HList avenue that Miles suggest is an interesting one.
– huynhjl Oct 3 at 4:42 @AdamPingel, I'm going to be honest here... You lost me at "limited by the zero". – huynhjl Oct 3 at 4:46 @huynjl Trying to adopt some of the language I've seen in Scalaz. In this case I hope I'm using "zero" along these lines: github.Com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/… – Adam Pingel Oct 3 at 5:05.
Ok no scalaz and no solution but an explanation. If you use your f.curried. Apply with 1 and then with 2 arguments in the REPL observe the return-result types DO actually differ each time!
FoldLeft is quite simple. It's fixed in it's type with your starting argument which is f. Curried and since that has not the same signature as f.curried.
Apply(1) it doesn't work. So the starting argument and the result HAVE to be of the same type. The type hast to be consistent for the starting-sum element of foldLeft.
And your result would be even Int so that would absolutely not work. Hope this helps.
– Adam Pingel Sep 30 at 7:17 @AdamP see chuusai.Com/2011/06/09/scala-union-types-curry-howard – Arjan Blokzijl Sep 30 at 7:34 Directly using Sabin's notation in this case would be cumbersome. If there were a way to turn the "T1 => ... => Tn" type into the union "(T1 => ... => Tn ) v ... v (Tn-1 => Tn)" with some special operator, that would be very useful here. – Adam Pingel Sep 30 at 7:47 My mobile prevented me from postage tat link :/ but you can always google that too.
There isn't much(yet) material on that topic using scala. – AndreasScheinert Sep 30 at 7:54 Thank you Andreas and @ArjanBlokzijl for your comments. I'm curious if it's possible to extend Sabin's union types as mentioned in my previous comment.(And now included in the original post's update.) – Adam Pingel Sep 30 at 7:55.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.