代码之家  ›  专栏  ›  技术社区  ›  oxbow_lakes

如何从scala中的a=>b=>c得到(a,b)=>c?

  •  17
  • oxbow_lakes  · 技术社区  · 14 年前

    如果我有:

    val f : A => B => C
    

    以下简称:

    val f : Function1[A, Function1[B, C]]
    

    我怎样才能得到一个函数 g 签字:

    val g : (A, B) => C = error("todo")
    

    (即)

    val g : Function2[A, B, C] //or possibly
    val g : Function1[(A, B), C]
    

    依据 f ?

    4 回复  |  直到 9 年前
        1
  •  23
  •   retronym    14 年前
    scala> val f : Int => Int => Int = a => b => a + b
    f: (Int) => (Int) => Int = <function1>
    
    scala> Function.uncurried(f)
    res0: (Int, Int) => Int = <function2>
    
        2
  •  13
  •   Dave Griffith    14 年前

    为了完整性,扩展转喻的答案

    val f : Int => Int => Int = a => b => a + b
    val g: (Int, Int) => Int = Function.uncurried(f)
    val h: ((Int, Int)) => Int = Function.tupled(g)
    

    这两个操作的转换函数也在函数对象上提供,因此如果您愿意,可以将上面的内容向后写。

    val h: ((Int, Int)) => Int =  x =>(x._1 + x._2)
    val g: (Int, Int) => Int = Function.untupled(h)
    val f : Int => Int => Int = g.curried  //Function.curried(g) would also work, but is deprecated. Wierd
    
        3
  •  9
  •   Rex Kerr    14 年前

    为了解决这个问题,虽然有一个库方法可以做到这一点,但手工操作也可能具有指导意义:

    scala> val f = (i: Int) => ((s: String) => i*s.length)
    f: (Int) => (String) => Int = <function1>
    
    scala> val g = (i: Int, s: String) => f(i)(s)
    g: (Int, String) => Int = <function2>
    

    或者一般说来,

    def uncurry[A,B,C](f: A=>B=>C): (A,B)=>C = {
      (a: A, b: B) => f(a)(b)
    }
    
        4
  •  1
  •   Jus12    9 年前

    与雷克斯·克尔的答案相似,但更容易阅读。

    type A = String
    type B = Int
    type C = Boolean
    
    val f: A => B => C = s => i => s.toInt+i > 10
    
    val f1: (A, B) => C = f(_)(_)