php高级函数编程-创建类似于ramdaJS的curry方法

php高级函数编程-创建类似于ramdaJS的curry方法,php,functional-programming,currying,partial-application,ramda.js,Php,Functional Programming,Currying,Partial Application,Ramda.js,要求: 占位符支架 部分应用函数可以应用于部分应用函数 咖喱 5.6 PHP支持 这里是我的尝试,但是它只支持hhvm 3.7,正如您在上的示例中所看到的 $getLadies结果是否可以在PHP5.6中实现,而不仅仅是hhvm 这并不漂亮,但这应该是Ramda当前的curry功能的一个近似模拟 namespace Phamda { function _() { static $placeholder; if ($placeholder === null)

要求:

  • 占位符支架
  • 部分应用函数可以应用于部分应用函数
  • 咖喱
  • 5.6 PHP支持
  • 这里是我的尝试,但是它只支持hhvm 3.7,正如您在上的示例中所看到的


    $getLadies结果是否可以在PHP5.6中实现,而不仅仅是hhvm

    这并不漂亮,但这应该是Ramda当前的
    curry
    功能的一个近似模拟

    namespace Phamda {
        function _() {
            static $placeholder;
            if ($placeholder === null) {
                $placeholder = new \stdClass;
            }
            return $placeholder;
        }
    
        function curryN($n, $f) {
            $curryNRec = function($recv) use ($n, $f, &$curryNRec) {
                return function () use ($recv, $n, $f, &$curryNRec) {
                    $left = $n;
                    $argsIdx = 0;
                    $combined = array();
                    $combindedIdx = 0;
                    $args = func_get_args();
                    while ($combindedIdx < count($recv) || $argsIdx < count($args)) {
                        if ($combindedIdx < count($recv)
                            && ($recv[$combindedIdx] !== _() || $argsIdx > count($args))) {
                            $result = $recv[$combindedIdx];
                        } else {
                            $result = $args[$argsIdx];
                            $argsIdx += 1;
                        }
                        $combined[$combindedIdx] = $result;
                        $combindedIdx += 1;
                        if ($result !== _()) {
                            $left -= 1;
                        }
                    }
                    if ($left <= 0) {
                        return call_user_func_array($f, $combined);
                    } else {
                        return $curryNRec($combined);
                    }
                };
            };
            return $curryNRec([]);
        }
    
        function curry($f) {
            $fRefl = new \ReflectionFunction($f);
            return curryN($fRefl->getNumberOfParameters(), $f);
        }
    }
    
    您可以从以下位置使用和功能:

    $resultset = json_decode('[{
      "id": 1,
      "gender": "Male",
      "name": "Matthew"
    }, {
      "id": 2,
      "gender": "Male",
      "name": "Willie"
    }, {
      "id": 3,
      "gender": "Female",
      "name": "Ann"
    }, {
      "id": 4,
      "gender": "Female",
      "name": "Margaret"
    }, {
      "id": 5,
      "gender": "Female",
      "name": "Marie"
    }]',TRUE);
    
    $filterGender = function($row,$gender){
        return $row['gender']==$gender;
    };
    
    $detectMen = curry($filterGender,(new Placeholder),'Male');
    $detectWomen = curry($filterGender,(new Placeholder),'Female');
    
    var_dump($detectMen(['gender'=>'Male'])); //works -- expected result TRUE
    
    $getLadies = curry('array_filter',(new Placeholder),$detectWomen);
    
    var_dump($getLadies($resultset)); //does not work -- expected result Ladies from result set
    
    namespace Phamda {
        function _() {
            static $placeholder;
            if ($placeholder === null) {
                $placeholder = new \stdClass;
            }
            return $placeholder;
        }
    
        function curryN($n, $f) {
            $curryNRec = function($recv) use ($n, $f, &$curryNRec) {
                return function () use ($recv, $n, $f, &$curryNRec) {
                    $left = $n;
                    $argsIdx = 0;
                    $combined = array();
                    $combindedIdx = 0;
                    $args = func_get_args();
                    while ($combindedIdx < count($recv) || $argsIdx < count($args)) {
                        if ($combindedIdx < count($recv)
                            && ($recv[$combindedIdx] !== _() || $argsIdx > count($args))) {
                            $result = $recv[$combindedIdx];
                        } else {
                            $result = $args[$argsIdx];
                            $argsIdx += 1;
                        }
                        $combined[$combindedIdx] = $result;
                        $combindedIdx += 1;
                        if ($result !== _()) {
                            $left -= 1;
                        }
                    }
                    if ($left <= 0) {
                        return call_user_func_array($f, $combined);
                    } else {
                        return $curryNRec($combined);
                    }
                };
            };
            return $curryNRec([]);
        }
    
        function curry($f) {
            $fRefl = new \ReflectionFunction($f);
            return curryN($fRefl->getNumberOfParameters(), $f);
        }
    }
    
    use Phamda as P;
    
    $resultset = json_decode('[{
      "id": 1,
      "gender": "Male",
      "name": "Matthew"
    }, {
      "id": 2,
      "gender": "Male",
      "name": "Willie"
    }, {
      "id": 3,
      "gender": "Female",
      "name": "Ann"
    }, {
      "id": 4,
      "gender": "Female",
      "name": "Margaret"
    }, {
      "id": 5,
      "gender": "Female",
      "name": "Marie"
    }]', true);
    
    $filterGender = P\curry(function($row, $gender){
        return $row['gender'] == $gender;
    });
    
    $detectMen = $filterGender(P\_(), 'Male');
    $detectWomen = $filterGender(P\_(), 'Female');
    
    var_dump($detectMen(['gender' => 'Male']));
    // bool(true)
    
    $filter = P\curry('array_filter');
    $getLadies = $filter(P\_(), $detectWomen);
    
    var_dump($getLadies($resultset));
    /*
    array(3) {
      [2] =>
      array(3) {
        'id' =>
        int(3)
        'gender' =>
        string(6) "Female"
        'name' =>
        string(3) "Ann"
      }
      [3] =>
      array(3) {
        'id' =>
        int(4)
        'gender' =>
        string(6) "Female"
        'name' =>
        string(8) "Margaret"
      }
      [4] =>
      array(3) {
        'id' =>
        int(5)
        'gender' =>
        string(6) "Female"
        'name' =>
        string(5) "Marie"
      }
    }
    */
    
    use function nspl\f\rpartial;
    
    $detectMen = rpartial($filterGender, 'Male');
    $detectWomen = rpartial($filterGender, 'Female');
    
    var_dump($detectMen(array('gender' => 'Male')));
    
    $getLadies = rpartial('array_filter', $detectWomen);
    
    var_dump($getLadies($resultset));