【问题标题】:Can `A => List[B]` be transformed into a `List[A => B]`?`A => List[B]` 可以转换成 `List[A => B]` 吗?
【发布时间】:2021-04-03 20:57:29
【问题描述】:

我正在尝试为这个 Scala 函数签名找到一个实现:

def explode[A, B](f: A => List[B]): List[A => B]

相反的方向是可能的:

def nest[A, B](fs: List[A => B]): A => List[B] = (a: A) => fs.map(_(a))

现在我倾向于相信第一个 (explode) 是无法实现的,但我很高兴被证明是错误的。如果确实无法实现,是不是有深层次的原因?

在我看来,我实际上是在要求编译器“复制”输入 A 一些 n 次(Lists 大小),并将其“修复”为输入。

【问题讨论】:

  • @LuisMiguelMejíaSuárez 见here。 (另外,它们的功能并不完全相同,每个都会产生不同的B
  • 是的,对不起。我仍然认为值得解释一下你想做什么
  • 为什么不使用元组列表呢?还是地图?类似的东西:def explode[A, B](f: A => List[B])(a: A): List[(A, B)] = { f(a).map(b => a -> b) } ?

标签: scala function types functional-programming function-composition


【解决方案1】:

在我看来,我实际上是在要求编译器“复制”输入 A 一些 n 次(Lists 大小),并将其“修复”为输入。

问题是你不知道n 是什么。例如,考虑一个函数,它返回一个数字的所有主要除数的列表:

def divisors(n: Int): List[Int] = ???

你期望explode(divisors) 是什么? divisors 可以返回任意大小的 List,具体取决于它的参数,无论何时调用它。但是当你调用explode 时,它必须立即返回一个固定大小的List

给定一个固定类型A,你的代码中的签名可以这样写:

type F[T] = List[T]
type G[T] = A => T

def nest[B]: F[G[B]] => G[F[B]]
def explode[B]: G[F[B]] => F[G[B]]

nestexplode 让人想起 sequence 操作。它适用于nest,因为可以为List 编写Traverse 实例,但不能为函数A => T 编写Traverse 实例。这是一个等效的question for Haskell,它提供了更多的洞察力。

【讨论】:

  • 感谢您提供信息丰富的回复!你写:“......但是当你调用nest时,它必须立即返回一个固定大小的列表。” (我相信你的意思是explode)。这是真的。如果我愿意立即放弃列表以固定大小返回的部分,我想知道答案是否会有所不同 - 如果我要使用 Stream / LazyList 等呢?
  • 我认为,Stream 还是不好,因为它可以立即耗尽它,例如explode(divisors).toList。对于某些nList 可能必须为空。是理论上的问题,还是你有什么想解决的问题?
  • 我明白你的意思。我认为空的List 可以正常工作,但本质仍然是机智的。这主要是理论上的,但它源于我正在尝试的一个副项目。恐怕给出更详细的上下文会太复杂而且无济于事。从本质上讲,这意味着我可能应该寻找另一个方向来建模我的问题。
【解决方案2】:

如果你想做一些满足签名的实现,你可以这样做:

def explode[A, B](f: A => List[B]): List[A => B] = {
  Nil
}

def explode[A, B](f: A => List[B]): List[A => B] = {
  List(f.andThen(_.head))
}

但我猜你想要一些语义不同的东西:

“重复”输入 A 一些 n 次(列表大小),并“修复”它 作为输入

在这种情况下,有一个问题。在一般情况下,f 的结果取决于输入 A。它可以是 Nil、有限大小列表或无限列表。

你能做的只是:

def explode[A, B](f: A => List[B]): A => List[A => B] = {
  f.andThen(_.map(b => (_: A) => b)
}

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 2012-10-11
    • 1970-01-01
    • 2016-09-16
    • 2011-12-06
    • 2011-03-03
    相关资源
    最近更新 更多