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

Why not define functions as singleton functions?

考虑在无形回购中找到的 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 = ???
}

注意 call-site 现在是如何变成的

isSatisfyingSomePredicate(foo)

而不是

UtilWithASingleMethod.isSatisfyingSomePredicate(foo)

import UtilWithASingleMethod._

isSatisfyingSomePredicate(foo)

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

除了不熟悉或与工厂模式中使用的 object+apply 样式混淆等主观缺点外,单例函数定义是否存在任何技术缺点?

他们必须在您链接的文件中创建单例对象的原因是这些不是函数,而是多态函数,也就是说,他们有一个 apply[T](a: F[T]): G[T] 方法,该方法由类型参数 T 普遍量化。这对于普通函数来说根本不需要,它所做的只是增加在单例对象 foo 上调用 apply 方法的开销,而不是直接调用 foo 方法。它对你 "avoid" 包和导入也没有帮助,因为无论如何你都想在某个包中拥有这个对象,你不想将它转储到默认的根包中。

如果你想避免"forced" UtilWithASingleMethod命名空间,那么直接将isSatisfyingSomePredicate添加到util:

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

一旦您导入此方法就可用 util._

Scala 3 (Dotty) 支持 toplevel definitions,而不是

package utils

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

我们可以去掉间接寻址然后写

package utils

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

这确实解决了我的问题。