2

我是 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?*/
   }
4

2 回答 2

3

要使用具有 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
于 2013-01-30T16:07:47.713 回答
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
        }
    }
}
于 2013-01-30T17:38:10.857 回答