Mic*_*ael 10 functional-programming scala function composition
我理解为什么功能组成很重要.它允许从小而简单的功能构建大型复杂功能.
val f: A => B = ... val g: B => C = ... val h = f andThen g; // compose f and g
该构图符合身份和相关性法则.
关联性很有用,因为它允许f1 andThen f2 andThen f3 andThen f4 ...以任何顺序进行分组.现在我想知道为什么身份是有用的.
def f[T](t:T) = t // identity function val g: A => B = ... // just any function g andThen f[B] == f[A] andThen g
所以,我的问题是这个身份在哪里以及为何有用.
Rex*_*err 10
只要界面为您提供比实际需要更多的控制,身份就很有用.例如,Either没有flatten方法.我们假设你有
val e: Either[Double, Float] = Right(1.0f)
Run Code Online (Sandbox Code Playgroud)
而你想把它压平成一个Double.你怎么做呢?有一种方便的fold方法,但没有方法将右侧转换为左侧的类型.那么你
e.fold(identity, _.toDouble)
Run Code Online (Sandbox Code Playgroud)
你得到了你想要的东西.
从更理论的角度来看(因为我可以猜测这个问题是从哪里产生的),恒等函数的一个基本用途是它们允许您定义同构的概念,这通常是一个更有用的定义比通常的平等更“相同”(读这个)。
同构告诉你“去那里再回来和呆在这里是一样的”。在类似集合的结构中,该定义对应于双射函数 - 但并非所有东西都是类似集合的。因此,一般来说,我们可以说:f如果存在 a g(其逆),使得f . g == id和,则函数(态射)是同构g . f == id。请注意,这关键取决于具有id:我们一般不能假设事物具有我们可以引用的“元素”,就像我们在引入双射函数时通常所做的那样。
这是一个非基于集合的示例:考虑有向图。假设有顶点A -> B和B -> A。由于路径可以(关联地!)连接,因此我们有路径A -> B -> A、 和B -> A -> B。A -> A但它们与循环和B -> B(或“停留在一个边缘”)只是“同一件事” !A我们现在也可以说这些是和的恒等路径B。根本不涉及双射或“forall x in A ...”。
所有这些结构也可以用编程中的类别来描述(并使用)(Scala、Haskell);例如,管道形成一个类别,因此需要具有身份管道。
除此之外,这里还有另一个实际用途,用作id折叠的基值:
doAll = foldr (.) id [(+1), (*2), (3-)]
Run Code Online (Sandbox Code Playgroud)
结合了许多内功能的简短版本。
小智 5
通常,您通过分解公共部分来优化公式或代码或其他任何内容。也就是说,DRY 原则说a ? v + x : v包含冗余——你输入v两次表达式。您必须将代码重写为最佳形式(a ? x: 0) + v。你看,我们已经分解了公共部分。你很想这样做
if (!initialized) initialize(callback_with_very_long_name) else callback_with_very_long_name
Run Code Online (Sandbox Code Playgroud)
如有必要,它会初始化一些东西并以任何一种方式调用回调。这看起来与上面的数学公式非常相似。您可以轻松地分解出数学/逻辑表达式中的公因子,但是如何分解出函数应用程序?如果您了解数学或 Hascel,您应该看到
a ? x + v : v = v + (a ? x : 0)
Run Code Online (Sandbox Code Playgroud)
看起来很像
a ? f value : value = ???
Run Code Online (Sandbox Code Playgroud)
在一种情况下添加 x 但在另一种情况下不添加。您在一种情况下将函数应用于该值,但在另一种情况下不适用。您将前者优化为(a ? x : 0) + v因为 0 是附加标识(添加到它时不会改变任何内容)并且v是这里的一个常见因素,无论application of x. 在函数应用(或不应用)的情况下,回调是共同的因素。我们想把它分解出来。我们应该对它应用什么恒等函数以使值不会改变?身份功能!
(a ? f : identity) value
Run Code Online (Sandbox Code Playgroud)
是我们正在寻找的。我们已经摆脱了冗余。我们的原始示例如下所示
(initialized ? identity : initialize) (callback_with_very_long_name)
Run Code Online (Sandbox Code Playgroud)
请注意,它现在适合一页的一行。我以这种方式提出它是为了强调“为什么我们需要不需要的东西”这个问题不是特定于Scala的。
恒等函数是函数组合的恒等元素,例如 1 表示乘法,0 表示加法。我们需要它就像需要 1 或 0 一样。例如,假设我们正在编写一个(高阶)函数,它接受一个函数列表并返回它们的组合:然后很自然地返回一个空列表的恒等函数。这就像如果我们正在编写一个接受整数列表并返回它们的总和的函数,我们会为空列表返回 0。
| 归档时间: |
|
| 查看次数: |
1786 次 |
| 最近记录: |