code: function wrapFunctionCond(_typeVarMap, index, value) {
        var expType = typeInfo.types[index];
        if (expType.type !== FUNCTION) return value;
  
        //  checkValue :: (TypeVarMap, Integer, String, a) -> Either (() -> Error) TypeVarMap
        function checkValue(typeVarMap, index, k, x) {
          var propPath = [k];
          var t = expType.types[k];
          return (
            t.type === VARIABLE ?
              Z.chain (
                function(typeVarMap) {
                  return isEmpty (typeVarMap[t.name].types) ?
                    Left (function() {
                      return typeVarConstraintViolation (
                        env,
                        typeInfo,
                        index,
                        propPath,
                        typeVarMap[t.name].valuesByPath
                      );
                    }) :
                    Right (typeVarMap);
                },
                Right (updateTypeVarMap (env,
                                         typeVarMap,
                                         t,
                                         index,
                                         propPath,
                                         [x]))
              ) :
            // else
              Z.map (
                function(r) { return r.typeVarMap; },
                satisfactoryTypes (env,
                                   typeInfo,
                                   typeVarMap,
                                   t,
                                   index,
                                   propPath,
                                   [x])
              )
          );
        }
  
        var typeVarMap = _typeVarMap;
        return function(x) {
          if (arguments.length !== expType.arity - 1) {
            throw invalidArgumentsLength (typeInfo,
                                          index,
                                          expType.arity - 1,
                                          slice.call (arguments));
          }
  
          var args = arguments;
          typeVarMap = assertRight (
            (init (expType.keys)).reduce (function(either, k, idx) {
              var arg = args[idx];
              return Z.chain (function(typeVarMap) {
                return checkValue (typeVarMap, index, k, arg);
              }, either);
            }, Right (typeVarMap))
          );
  
          var output = value.apply (this, arguments);
          var k = last (expType.keys);
          typeVarMap = assertRight (checkValue (typeVarMap, index, k, output));
          return output;
        };
      }
docs: wrapFunctionCond :: (TypeVarMap, Integer, a) -> a