简体   繁体   English

def foo [A,B]到底是什么意思? 输入阴影

[英]What exactly does def foo[A,B] mean? Type shadowing

When I write a function like def foo[A,B] , what exactly does the [A,B] mean? 当我写这样一个函数def foo[A,B]不正是[A,B]是什么意思? I know it's a Polymorphic Method ; 我知道这是一种多态方法 but when do you use foo [A] versus foo [A,B] ? 但是何时使用foo [A]foo [A,B]

Here's an example where I don't understand the difference. 这是一个我不了解其中差异的示例。 This function compiles: 该函数编译:

def map[B](f: A => B): Stream[B] =                                               
  foldRight(empty[B])((h,t) => cons(f(h), t))

Whereas this one doesn't compile. 而这个不编译。 I don't understand why the A isn't required, after all A is referenced by the f: A => B : 我不明白为什么A不是必需的,毕竟A被引用的f: A => B

def map[A,B](f: A => B): Stream[B] =                                            
  foldRight(empty[B])((h,t) => cons(f(h), t))

[error] ..../Stream.scala:61: type mismatch;
[error]  found   : h.type (with underlying type A)
[error]  required: A
[error]     foldRight(empty[B])((h,t) => cons(f(h), t))

(this is from one of the FP in Scala exercises) (这是Scala练习中的FP之一

Addendum 附录

After reading the answers I'm adding some context, to help future readers. 阅读答案后,我会添加一些上下文,以帮助将来的读者。 The function is defined inside a trait: 该函数在特征内定义:

trait Stream[+A] { 
  ...
  def map[B](f: A => B):Stream[B] = 
    foldRight(empty[B])((h,t) => cons(f(h), t))
  ...
}

So the error was being caused by type shadowing , but see @acjay's excellent answer below. 因此,错误是由阴影类型引起的,但请参见下面的@acjay最佳答案。

Googling scala type shadowing doesn't result in a direct definition in any of the scala docs, which is interesting because as @travisbrown says below, it's "one of the most common sources of beginner confusion I've seen". 谷歌搜索scala type shadowing不会在任何scala文档中产生直接定义,这很有趣,因为正如@travisbrown在下面说的那样,它是“我见过的最常见的初学者困惑源之一”。 There is a discussion here: Why does Scala support shadow variables? 这里有一个讨论: Scala为什么支持阴影变量?

In the first example, there's only one type parameter because that's not a function in isolation, it's a method in class Stream[A] , which declares the first type parameter. 在第一个示例中,只有一个类型参数,因为这不是孤立的函数,而是类Stream[A] ,该方法声明了第一个类型参数。 Approximately like so: 大概是这样的:

class Stream[A] {
  // ...

  def map[B](f: A => B): Stream[B] =                                               
    foldRight(empty[B])((h,t) => cons(f(h), t))

  // ...
}

So you get the A from the surrounding class scope. 因此,您可以从周围的类范围获得A Suppose instead that you made map a method on the companion object instead. 假设您改为在对应对象上使map成为方法。 In this case, the companion object has no type parameter, so you have to define both parameters on the method: 在这种情况下,伴随对象没有类型参数,因此您必须在方法上定义两个参数:

class Stream[A] {
  // ... methods, with foldRight, but no `map`
}

object Stream {
  // ...

  def map[A, B](stream: Stream[A])(f: A => B): Stream[B] =                                               
    stream.foldRight(empty[B])((h,t) => cons(f(h), t))

  // ...
}

This second option would be used slightly differently. 第二个选项的使用会稍有不同。 You would say Stream.map(myStream)(myMappingFunction) instead of myStream.map(myMappingFunction) . 您可能会说Stream.map(myStream)(myMappingFunction)而不是myStream.map(myMappingFunction) Both options are perfectly valid, but it's probably more idiomatic to put the method in the class. 这两个选项都是完全有效的,但是将方法放在类中可能更惯用。

So, to answer your question, you use multiple type parameters on a method when two or more of the arguments and/or return type need to be generic. 因此,要回答您的问题,当两个或多个参数和/或返回类型需要通用时,可以在方法上使用多个类型参数。 You might also use two type parameters for classes as well, like (disregarding variance): 您可能还会对类使用两个类型参数,例如(忽略方差):

Type Map[A, B] - A is the key type and B is the value type 类型Map[A, B] A是键类型, B是值类型

Type Tuple2[A, B] (better known as (A, B) ) - A is the type of the 1st element, B is the type of the 2nd element 类型Tuple2[A, B] (又称(A, B) )- A是第一个元素的类型, B是第二个元素的类型

Type Function1[A, B] (better known as A => B ) - A is the argument type, B is the return type 类型Function1[A, B] (又称A => BA是参数类型, B是返回类型

...and so on. ...等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM