为什么不将函数定义为单例函数?

Mar*_*lic 1 singleton scala package shapeless function-definition

考虑在无形状回购中找到的单例函数的定义:

/** Polymorphic function selecting an arbitrary element from a non-empty `Set`. */
object choose extends (Set ~> Option) {
  def apply[T](s : Set[T]) = s.headOption 
}
Run Code Online (Sandbox Code Playgroud)

def在以下示例中,将其与传统语法进行对比:

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)

package utils

object isSatisfyingSomePredicate extends (Foo => Boolean) {
  def apply(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)

注意呼叫站点现在如何变成

isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

代替

UtilWithASingleMethod.isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

要么

import UtilWithASingleMethod._

isSatisfyingSomePredicate(foo)
Run Code Online (Sandbox Code Playgroud)

就个人而言,UtilWithASingleMethod软件包似乎只是为了能够使用熟悉的def语法而没有添加任何有用的信息。

除了主观的缺点(例如不熟悉或与工厂模式中使用的对象+应用样式混淆)之外,单例函数定义还有其他技术缺点吗?

And*_*kin 5

他们之所以必须在链接的文件中创建单例对象,是因为它们不是函数,而是多态函数,即它们具有一种apply[T](a: F[T]): G[T]可以通过类型参数进行通用量化的方法T。普通函数根本不需要这样做,它所做的只是增加了apply在单例对象上调用方法的开销,foo而不是foo直接调用该方法。它也无助于“避免”软件包和导入,因为无论如何您都希望将此对象包含在某个软件包中,所以您不想将其转储到默认的根软件包中。

如果要避免使用“强制” UtilWithASingleMethod命名空间,则将isSatisfyingSomePredicate直接添加到util

package object util {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}
Run Code Online (Sandbox Code Playgroud)

导入后即可使用此方法util._

  • @MarioGalic如果不想进一步打包,则将方法直接添加到util包中。幸运的是,Scala正是为此提供了包装对象。我的意思是,您可以按字面意思编写`package对象util {def isSatisfyingSomePredicate(f:Foo):Boolean = ??? },然后导入`util._`将自动将`isSatisfyingSomePredicate`纳入范围。 (2认同)