94 karma · joined December 31, 2013
Here is how I read this in case it helps anyone
Def zip[A, B](a: ⇒ F[A], b: ⇒ F[B]): F[(A, B)]
F[Something] is a “container type” or a type constructor, a type that is parameterized by another type, for example F[Int] could be List[Int] or Future[Int].The method zip has two parameters, one a by name reference to something of type F[A] and the other a by name reference to something of type F[B] and returns an F of the pair of input types (A, B)
Looks like this deals with three total types, a container type F that must be the same for input param a, input param b, and the result.
I know nothing about F other than the fact that it contains another type. I know nothing about A and nothing about B which means I can’t be looking them up somewhere or using defaults, so the only way I could possibly return an F[(A, B)] is if I combined the two inputs.
Also, code written in this style is meant to follow the substitution principle, so I’ll think through a couple of substitutions to see how this method could be useful to me.
For: F = List, A = Int, B = String
Def zip[Int, String](a: => List[Int], b: => List[String]): List[(Int, String)]
Since I can’t invent new members of list and the two members of the list may be different lengths, this must return a list whose length is the minimum of a.length and b.length containing and int -> string mapping. Handy.F = Future, A = User, B = LastLoginDate
Def zip[User, LastLoginDate](a: => Future[User], b: => Future[LastLoginDate]): Future[(User, LastLoginDate)]
This can only return me a User if they have logged in at least once. The fact that it is two Futures makes me think I am probably querying two remote servers for this information and that I can’t resolve the new Future until both of the input Futures have resolved. By the time this Future is ready I will have a User with their last login date or the Future will fail.F = Option, A = IpAddress, B = Port
Def zip[IpAddress, Port](a: => Option[IpAddress], b: => Option[Port]): Option[(IpAddress, Port)]
I may have an IpAddress, I may have a Port, either return to me both the IpAddress and the Port, or neither.
This one is really easy to map out as their are only 4 possible code paths Some(IpAddress), Some(Port) => Some(IpAddress, Port)
Some(IpAddress), None => None
None, Some(Port) => None
None, None => None
I agree some documentation explaining this would be nice, but there is considerable information I can pull from this signature.