library ArrayUtils {
    function map(uint[] memory self, function (uint) pure returns (uint) f)
        internal
        pure
        returns (
            uint[] memory r
        )
    {
        r = new uint[]( self.length);
        for (uint i = 0; i < self.length; i++) {
            r[i] = f(self[i]);
        }
    }

    function reduce(
        uint[] memory self,
        function (uint, uint) pure returns (uint) f
    ) internal pure returns (uint256 r) {
        r = self[0];
        for (uint i = 1; i < self.length; i++) {
            r = f(r, self[i]);
        }
    }

    function range(uint256 length) internal pure returns (uint[] memory r) {
        r = new uint256[](length );
        for (uint i = 0; i < r.length; i++) {
            r[i] = i;
        }
    }

    function _castToPure(function(bytes memory) internal view fnIn)
returns (function(bytes memory) pure fnOut)
   {
       assembly {
           fnOut := fnIn
           }
        }
}
