Scala方法定义命名参数与未命名

时间:2013-01-30 15:58:34

标签: scala methods signature

我是Scala的新手,我有时会遇到方法签名。 让我们看看这段代码,我特别感兴趣的是命名参数以对它们进行进一步的操作。

def divide(xs: List[Int]): List[Int] = {
      val mid = xs.length/2
      (xs take mid, xs drop mid)
}

这里我定义了名为“xs”的输入列表,我在很多网页上看到了这个约定。但是在大学里,我们有另一种方法签名定义方法(我遗漏了名字,抱歉),我们没有命名输入参数,但发生了模式匹配:

   def mylength: List[Any] => Int = {
     case Nil   => 0
     case x::xs => mylength(xs)+1
   }

在这种情况下,识别输入参数非常简单,因为只有一个输入参数。如何在上面显示的编码样式中使用与下面代码中相同的样式和2个或更多输入参数?

   def myConcat(xs: List[Any], ys: List[Any]) = {
              xs ++ ys
   }

抱歉我的英文。我没有在谷歌上找到任何东西,因为我不太清楚什么条件可以搜索...

编辑:我必须坚持使用界面。我举了另一个例子,你可以帮助我。 myAppend1和myAppend2的行为方式相同,将新元素放在列表的前面。

   def myAppend1(xs: List[Any], y: Any): List[Any] = {
        y :: xs
   }

我现在的问题是在myAppend2中输入命名......

  def myAppend2: List[Any] => Any => List[Any] = {
           /* how can i do this here, when no names y/xs are given?*/
   }

2 个答案:

答案 0 :(得分:3)

要使用具有2个或更多参数的相同样式,只需将参数视为2的元组:

 def myConcat: (List[Any], List[Any]) => List[Any] = { 
   case (Nil, Nil) => List()
   case (xs,ys) => ... 
 }

我们来看myAppend示例:

 def myAppend2: (List[Any], Any) => List[Any] = {
    case (xs, y) => y :: xs 
 }

它具有(或多或少)相同的签名:

def myAppend1(xs: List[Any], y: Any): List[Any] = {
    y :: xs
}

用法:

scala> myAppend1(List(1,2,3), 4)
res3: List[Any] = List(4, 1, 2, 3)

scala> myAppend2(List(1,2,3), 4)
res4: List[Any] = List(4, 1, 2, 3)

如果你有一个想要函数参数(List[Any], Any) = List[Any]的高阶函数,那么两者都可以工作,并且(对于大多数实际用途)是等价的。

请注意,将其定义为

def myAppend3: List[Any] => Any => List[Any] = {
   xs => y => y::xs
}

你将创建一个curried函数,在scala中有一个不同的签名 (根据你的意愿):

 myAppend3(List(1,2,3), 4) // won't compile
 myAppend3(List(1,2,3))(4) // need to do this

答案 1 :(得分:1)

def myAppend2: List[Any] => Any => List[Any] = { xs => y => 
    y :: xs
}

具有完整形式的函数文字语法:

def myAppend2: List[Any] => Any => List[Any] = {
    (xs: List[Any]) => {
        (y: Any) => {
            y :: xs
        }
    }
}