什么样的功能被视为“可组合”? [英] What kinds of functions are considered as "composable"?

查看:93
本文介绍了什么样的功能被视为“可组合”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

维基百科文章功能组合(计算机科学)说:


像数学中通常的函数组合一样,每个函数的结果都作为下一个的参数传递,最后一个的结果是


我有两个问题:


  1. 一个可组合的函数必须同时具有参数和返回值吗?



    所以下面的函数不是:

      def doNothing():Unit =()
    def myName():String =我的名字
    def eat(food:String ):Unit =()

    我的理解是否正确?

  2. $ b
  3. 可以这个函数副作用吗?

      def hello(name:String):String = { 
    println(name:+ name)//副作用
    名称+!
    }

    我们仍然认为它是可组合的吗?



解决方案

数学形式语言与编程中更多口语语言的混合使得这些对话变得困难。你正在处理两个上下文加载的单词:composable和function。

函数组合—在数学中



函数 A→B 的数学概念是从某个集合A到某些集合的映射设置B,并且函数组合是由表示的特定操作。对于某些 f:A→B g:B→C f 是一个函数 A→C ,使得(f∘g)(x)= f(g(x))对于 A 中的所有 x 。如果它们的域/ codomain以这种方式匹配(换句话说,这样的一对函数可以被组合),那么这个组合被定义为任何两个函数,并且我们通过声明函数是可组合的来描述它。 p>

可组合性—在编程中,作为一个定性术语,我们通常在软件中使用可组合性来描述一组组合可以通过组合小组合构建大型组合的能力。从这个意义上讲,程序员将函数(作为一个整体)描述为非常可组合的,因为函数可以(以及像Haskell这样的纯函数式语言)构成整个程序的大小。



在软件中,我们也看到了更多以人为本的术语可组合,它倾向于与模块化相关联。当组件是无状态的,关注点是分开的,并且API具有低表面积,所以更容易编写程序而不会犯错误。我们称赞这样一种设计的组件是可组合的 - 不仅仅是因为它们可以结合,而是因为它们 能够正确地结合 / em>。

功能—在编程中我会用稍微过时的术语子程序,因为我不知道用我们这个时代的说法来讨论这个问题的好方法。如果一个子程序没有做任何IO(并且总是停止,并且不抛出hellip;),那么它在数学意义上实现(或是)一个函数。 IO子程序与函数具有表面相似性,因为它们可能具有输入和输出值,但相似性在那里停止。我们之前讨论过的关于函数组合的讨论并不适用。



这里是我们遇到最棘手的语言困难的地方,因为函数已经成为通常用来引用任何子例程,甚至是执行IO的子例程。 FP爱好者倾向于打击这种 - 人们会说如果它是IO,它不是一个功能 - 但是这种流行的战斗已经失去了,现在没有回头路了。在大多数编程语境中,所有子例程都称为函数,区分满足数学定义的函数的唯一方法是称它们为纯函数。




考虑到这一背景,我恭敬地声称你的问题相当无趣,而且如果我们要从这个讨论中获得任何价值,他们需要额外的动机和背景。 b
$ b

一个可组合的函数必须同时具有参数和返回值吗?



有几个无聊的事情要指出这个问题。首先,Scala中的每个函数在技术上都有一个返回类型。如果这种类型是 Unit ,为简洁起见,它可能会被忽略,但它仍然是一种返回类型。



零(0-arg)函数可以简单地转换为具有参数的等价函数。所以真的,这没关系。如果您处于需要使用参数编写函数的情况,并且 f 没有参数,您可以只写 _ => f



这个功能有副作用吗?



语义争执。在Scala中,最合适的是它是一个 Function (或者从技术上说是一个方法,取决于定义的位置),但是由于对于副作用来说,它不是纯粹的功能。



我们仍然认为它是'可组合的'吗?



排序。所有这些东西仍然以相当一般的方式汇合在一起,所以是的,它们在软件意义上构成。虽然纯粹的功能比不纯的功能更好。而函数组合的数学概念并不适用于不是纯函数的子例程。

最后,如果你想知道它们是否在Scala中用<$ compose 方法c> Function1 ,你不需要堆栈溢出;只需要问编译器即可。


The Wikipedia article Function composition (computer science) says:

Like the usual composition of functions in mathematics, the result of each function is passed as the argument of the next, and the result of the last one is the result of the whole.

I have two questions about it:

  1. A composable function must have both arguments and return value?

    So following functions are not:

    def doNothing(): Unit = ()
    def myName(): String = "My name"
    def eat(food:String): Unit = ()
    

    Is my understanding correct?

  2. Can this function side-effect?

    def hello(name:String):String = {
      println("name: " + name) // side-effect
      name + "!"
    }
    

    Do we still consider it as "composable"?

解决方案

The mixture of formal language from math with more colloquial language from programming makes these conversations difficult. You're dealing with two contextually-loaded words here: "composable" and "function".

Function composition — in math

The mathematical notion of a "function" A → B is a mapping from some set A to some set B, and "function composition" is a specific operation denoted by . For some f: A → B and g: B → C, f∘g is a function A → C such that (f∘g)(x) = f(g(x)) for all x in A. This composition is defined for any two functions if their domain/codomain match up in this way (in other words, such a pair of functions "can be composed"), and we describe this by stating that "functions are composable".

Composability — in programming

As a qualitative term, we use "composability" often in software to describe the ability of a set of compositions can build large things from combining small ones. In this sense, programmers describe functions (as a whole) as "very composable", because functions can (and, in a purely functional language like Haskell, do) comprise the large and the small of an entire program.

In software we also see a more human-oriented usage of the term "composable" which tends to be associated with "modularity". When components are stateless, concerns are separated, and APIs have low surface area, it's easier to compose programs without making mistakes. We praise the components of such a design as being "composable"—not just because they can be combined, but because they're easy to combine correctly.

Function — in programming

I'm going to use the slightly outdated term "subroutine", because I don't know a good way to discuss this in the parlance of our times. If a subroutine doesn't do any IO (and always halts, and doesn't throw…), then it implements (or "is") a "function" in the mathematical sense. IO subroutines have superficial resemblance to functions, because they may have input and output values, but the similarity stops there. None of the conversations we may have about "function composition" as we first discussed it will apply.

Here's where we hit the trickiest linguistic difficulty, because the word "function" has come into common usage to refer to any subroutine, even ones that perform IO. FP enthusiasts tend to fight this—people say things like "if it does IO, it isn't a function"—but that battle of popularity has been lost and there's no turning back now. Within most programming contexts, all subroutines are called "functions", and the only way to distinguish functions that satisfy the mathematical definition is to call them "pure functions".


With this background in mind, I respectfully claim that your questions are fairly uninteresting, and that they require additional motivation and context if we are to derive any value from this discussion.

"A composable function must have both arguments and return value?"

There are a couple boring things to point out about this question. First, every function in Scala technically has a return type. If that type is Unit, it may be elided for brevity, but it's still a return type.

And a nullary (0-arg) function can be trivially transformed into an equivalent function with an argument. So really, it just doesn't matter. If you're in a situation where you need to compose functions with arguments and f has no argument, you can just write _ => f.

"Can this function have side-effect?"

Merely a semantic squabble. In the context of Scala, the most appropriate thing to say is that it is a Function (or perhaps technically a "method", depending on where it is defined), but due to the side effect, it is not a pure function.

"Do we still consider it as 'composable'?"

Sort of. All of these things still "come together" in a fairly general way, so yes, they do compose in the software sense. Although pure functions compose better than impure ones. And the mathematical notion of function composition does not apply to subroutines that are not pure functions.

Finally, if you want to know whether they literally compose in Scala with the compose method on Function1, you don't need Stack Overflow; just ask the compiler.

这篇关于什么样的功能被视为“可组合”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆