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

时间:2019-06-30 19:27:30

标签: scala package singleton shapeless function-definition

考虑在无形回购中发现的singleton function的定义:

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

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

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}

package utils

object isSatisfyingSomePredicate extends (Foo => Boolean) {
  def apply(foo: Foo): Boolean = ???
}

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

isSatisfyingSomePredicate(foo)

代替

UtilWithASingleMethod.isSatisfyingSomePredicate(foo)

import UtilWithASingleMethod._

isSatisfyingSomePredicate(foo)

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

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

2 个答案:

答案 0 :(得分:5)

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

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

util

此方法在您导入package object util { def isSatisfyingSomePredicate(foo: Foo): Boolean = ??? } 后就可以使用。

答案 1 :(得分:1)

Scala 3(Dotty)支持toplevel definitions,因此代替

package utils

object UtilWithASingleMethod {
  def isSatisfyingSomePredicate(foo: Foo): Boolean = ???
}

我们可以删除间接写入并写

package utils

def isSatisfyingSomePredicate(foo: Foo): Boolean = ???

这确实解决了我的问题。