Language agnostic 将链式链接发挥到极致的语言?

Language agnostic 将链式链接发挥到极致的语言?,language-agnostic,fluent-interface,method-chaining,Language Agnostic,Fluent Interface,Method Chaining,所以,我只是在想链接有多酷,它如何让事情更容易阅读。对于许多语言,当将一组函数应用于变量时,您会编写如下内容: i(h(g(f(x)))) 你必须从右到左或者从最里面到最外面去读。首先应用f,然后应用g,依此类推。但如果用链子锁住,它看起来更像 x|f|g|h|i 你可以像正常人一样阅读它。所以,我的问题是,一定有一些语言是这样做的,它们是什么?这些函数式编程语言就是这么做的吗 因此,我通常会创建一大堆临时变量,以便将其拆分为单独的行,使其更具可读性: a = f(x) b = g(a)

所以,我只是在想链接有多酷,它如何让事情更容易阅读。对于许多语言,当将一组函数应用于变量时,您会编写如下内容:

i(h(g(f(x))))
你必须从右到左或者从最里面到最外面去读。首先应用
f
,然后应用
g
,依此类推。但如果用链子锁住,它看起来更像

x|f|g|h|i
你可以像正常人一样阅读它。所以,我的问题是,一定有一些语言是这样做的,它们是什么?这些函数式编程语言就是这么做的吗


因此,我通常会创建一大堆临时变量,以便将其拆分为单独的行,使其更具可读性:

a = f(x)
b = g(a)
c = h(b)
what_i_really_wanted_all_along = i(c)
我的魔法语言在哪里,你仍然可以把它分成不同的行,如果它们变得太长,而不需要插入变量:

x | f
  | g
  | h
  | i

它不是函数式编程所独有的,尽管它可能最好用函数式语言实现,因为函数组合的整个概念完全属于函数式编程的领域

一方面,任何具有面向对象bent的语言都有返回类实例的方法的链接:

obj.method1().method2().method3(); // JavaScript
MyClass->new()->f()->g()->i(); # Perl

或者,这种链接模式最著名但最少的“编程语言”示例将是完全非OO和非函数的东西。。。你猜对了,Unix中的管道。与中一样,
ls | cut-c1-4 | sort-n
。既然shell编程被认为是一种语言,我说它是一个非常有效的例子。

它不是函数式编程的专利,尽管它可能最好用函数式语言实现,因为函数组合的整个概念完全属于函数式编程的领域

一方面,任何具有面向对象bent的语言都有返回类实例的方法的链接:

obj.method1().method2().method3(); // JavaScript
MyClass->new()->f()->g()->i(); # Perl
或者,这种链接模式最著名但最少的“编程语言”示例将是完全非OO和非函数的东西。。。你猜对了,Unix中的管道。与中一样,
ls | cut-c1-4 | sort-n
。既然shell编程被认为是一种语言,我说它是一个非常有效的例子。

是的,使用F#你有一个管道操作符
(也称为前向管道操作符,你有一个后向管道
F |>g |>h |>I

检查此选项,可以很好地了解实际使用情况。

是的,使用F#可以使用管道操作符
(也称为前向管道操作符,使用后向管道操作符
F |>g |>h |>i


勾选此项,可以很好地了解实际使用情况。

Haskell。以下三个示例是等效的:

  • i(h(g(f(x)))
    (嵌套函数调用)
  • x&f&g&h&i
    (根据要求从左到右链接)
  • (i.h.g.f)(x)
    (函数组合,在Haskell中更常见)


Haskell。以下三个示例是等效的:

  • i(h(g(f(x)))
    (嵌套函数调用)
  • x&f&g&h&i
    (根据要求从左到右链接)
  • (i.h.g.f)(x)
    (函数组合,在Haskell中更常见)


您所描述的基本上是流畅的界面模式

Wikipedia有一个来自多种语言的好例子:

马丁·福勒在这里写道:


正如DVK所指出的——任何OO语言,只要方法可以返回它所属类的实例,就可以提供这种功能。

您所描述的基本上是流畅的接口模式

Wikipedia有一个来自多种语言的好例子:

马丁·福勒在这里写道:


正如DVK所指出的——任何OO语言,只要方法可以返回它所属类的实例,就可以提供此功能。

好的,您可以在JavaScript及其相关语言中实现这一点:

function compose()
{
    var funcs = Array.prototype.slice.call(arguments);
    return function(x)
    {
        var i = 0, len = funcs.length;
        while(i < len)
        {
            x = funcs[i].call(null, x);
            ++i;
        }
        return x;
    }
}

function doubleIt(x) { print('Doubling...'); return x * 2; }

function addTwo(x) { print('Adding 2...'); return x + 2; }

function tripleIt(x) { print('Tripling...'); return x * 3; }

var theAnswer = compose(doubleIt, addTwo, tripleIt)( 6 );
print( 'The answer is: ' + theAnswer );
// Prints:
//   Doubling...
//   Adding 2...
//   Tripling...
//   The answer is: 42
函数组合()
{
var funcs=Array.prototype.slice.call(参数);
返回函数(x)
{
变量i=0,len=funcs.length;
而(我

如您所见,函数从左到右读取,对象和函数都不需要任何特殊实现。秘诀在于
compose

好的,您可以在JavaScript及其相关程序中实现这一点:

function compose()
{
    var funcs = Array.prototype.slice.call(arguments);
    return function(x)
    {
        var i = 0, len = funcs.length;
        while(i < len)
        {
            x = funcs[i].call(null, x);
            ++i;
        }
        return x;
    }
}

function doubleIt(x) { print('Doubling...'); return x * 2; }

function addTwo(x) { print('Adding 2...'); return x + 2; }

function tripleIt(x) { print('Tripling...'); return x * 3; }

var theAnswer = compose(doubleIt, addTwo, tripleIt)( 6 );
print( 'The answer is: ' + theAnswer );
// Prints:
//   Doubling...
//   Adding 2...
//   Tripling...
//   The answer is: 42
函数组合()
{
var funcs=Array.prototype.slice.call(参数);
返回函数(x)
{
变量i=0,len=funcs.length;
而(我

如您所见,函数从左到右读取,对象和函数都不需要任何特殊实现。秘密在于
compose

如果您通常不做一些数学运算,我不建议您使用它,但它肯定足够灵活,可以支持后缀符号。事实上,您
MapAll[Postfix, Cos[Sin[x]]]
(Postfix[x]//Sin)//Cos  
x // Sin // Cos  
Cos[Sin[x]]  
Cos[x] // Postfix
x // Cos
(x//Sin 
  // Cos
  // Exp 
  // Myfunct)  
Myfunct[E^Cos[Sin[x]]]  
x.f()
 .g()
 .h()
 .i();
static class Extensions 
{
    static T f<T>(this T x) { return x; }
    static T g<T>(this T x) { return x; }
    ...
}
infixr 1 >>>, <<<
(<<<) = (.) -- regular function composition
(>>>) = flip (.) -- flipped function composition

(f >>> g >>> h >>> i) x
    -- or --
(i <<< h <<< g <<< f) x
infixr 0 $
infixl 0 #
f $ x = f x -- regular function application
(%) = flip ($) -- flipped function application

i $ h $ g $ f $ x
    -- or --
x % f % g % h % i
(((x % f) % g) % h) % i -- intended
x % (f % (g % (h % i))) -- parse error (which then leads to type error)