Lifting (in the mathematical sense) functions

292 views
Skip to first unread message

rtm...@googlemail.com

unread,
Dec 3, 2016, 2:56:27 PM12/3/16
to scala-user
Hi all,
Scala provides .lift for various things like sets. I understand that *mathematically*, lift is an operator that moves a function from A => B to Collection[A] => Collection[B], or something like that.
map does that: List(1, 2, 3) map (_ *2)
but I thought it would be nice to apply it to functions. I decided to call it up and wrote some code like this

implicit def up[T, R](st: Seq[T])(f1: Function1[T, R]): Seq[R] = { st map f1 }

to pimp Function1. Ok, close but no cigar, my colleague had to fix it and got it working. I don't have the correct definition to hand but it worked and I could do stuff like (not tested here, but it did work)

 val add1 = (a: Int) => a + 1
 val double = (b: Int) => b * 2
val inp = List(1, 2, 3, 4)
add.up(double.up(inp))


to get

List(3, 5, 7, 9)

ie equivalent to

(inp map double) map add1     [ref 1]

but in a more set-based way (I have an SQL background which influences me a bit)

[1] can be traditionallly optimised to a single traversal:

 inp map (double andThen add1)

So I was wondering if Scala has some mechanism that would, using my .up notation, allow the function application to be delayed to the final functional call in a chain ie. so that in

val x = f3.up(f2.up(f1.up(inp)))   // maybe this can be written f3.up f2.up f1.up inp, not tried it

f1.up(inp) does not do anything but pass itself and its input 'inp' back to f2, which in turn passes itself and f1 and 'inp' back to f3, which can then say "I'm the last in the chain, so I'll compose myself and brothers upstream, and 'inp', to produce '(f3 andThen f2 andThen f1)'  then map that over 'inp' ".

Main question: can a function detect it's last in the call chain and take a different action?

Small question: is scala's .lift in any way related to the mathematical version of lifting ( A => B  -->  F[A] => F[B] ) I mentioined above. It really doesn't look like it, either as a generalisation or specialisation of it.

Any other thoughts? - I rather like the cleanliness of .up, and generalising it to muli-arg functions would seem to produce something like zipWith.

cheers

jan

Vlad Patryshev

unread,
Dec 4, 2016, 12:37:22 PM12/4/16
to rtm443x, scala-user
The notion of Functor is the key to treating all this mathematically. There are lots of tutorials.
Inventing a new math may be ok, but it will make more sense if you are somewhat familiar with the old one.

This may be useful too: http://www.staff.city.ac.uk/~ross/papers/Applicative.pdf - since it covers a lot of (now) popular issues regarding traversals etc.

Thanks,
-Vlad

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

rtm...@googlemail.com

unread,
Dec 4, 2016, 5:12:19 PM12/4/16
to scala-user, rtm...@googlemail.com
Thanks for the paper, I'll read it tomorrow.
But please note this is not anything novel mathematically; the lift I'm talking about is something I've come across several times. it's a scala implementation question mainly, so any pointers on how to get functions to compose 'intelligently', as above, would be appreciated.
This just seems like such a nice, clean thing syntactically, and to get an optimisation thrown in for free, well, what's not to like? [*]

thanks

jan

[*] probably lots, so I'm open to any criticism.

Thanks,
-Vlad

To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.

Vlad Patryshev

unread,
Dec 4, 2016, 8:34:04 PM12/4/16
to rtm443x, scala-user
Let's talk about it tomorrow, right after you finish reading the paper then.

Thanks,
-Vlad

To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+unsubscribe@googlegroups.com.

Oliver Ruebenacker

unread,
Dec 5, 2016, 10:33:33 AM12/5/16
to rtm...@googlemail.com, scala-user

     Hello,

  The lift method is inherited from PartialFunction. It converts a ParticalFuntion[A, B] into a function A => Option[B].

  Some collections are PFs: Map[K, V] is a PF[K, V], Seq[A] is a PF[Int, A] and Set[A] is a PF[A, Boolean].

     Best, Oliver

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

rtm...@googlemail.com

unread,
Dec 5, 2016, 11:31:25 AM12/5/16
to scala-user, rtm...@googlemail.com
Hi, I'm aware of scala's .lift on PFs and use it regularly in maps and sets (didn't know that a sequence could be lifted though, thanks for that). 

An example of lifting as I've seen it before can be found here <https://tpolecat.github.io/2014/03/21/functor.html>:

"We can use lift to take a function A => B to F[A] => F[B]
scala> F.lift((s:String) => s.length)(Box2("123", "x"))
res8: Box2[Int] = Box2(3,1)
"

This is exactly what I was talking about though done syntactically differently.

My main question still stands, is there any way of composing functions as I mentioned?

cheers

jan
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Jasper-M

unread,
Dec 5, 2016, 3:31:24 PM12/5/16
to scala-user, rtm...@googlemail.com
Aren't you just looking for something like a view?

scala> (List(1,2,3,4).view map double map add1).force
res0: Seq[Int] = List(3, 5, 7, 9)


Op maandag 5 december 2016 17:31:25 UTC+1 schreef rtm...@googlemail.com:

rtm...@googlemail.com

unread,
Dec 5, 2016, 6:00:22 PM12/5/16
to scala-user, rtm...@googlemail.com
Good spot. Didn't think of that.
It's not what I'm after actually, as I really was thinking of function manipulation and composition - think of it as primarily a learning exercise for me- not that there's anything wrong with what you've given, which is lazy-fying evaluation.

but nice, thanks

jan
Reply all
Reply to author
Forward
0 new messages