def loadfn(fn, *args, **kwargs):
    """
    Loads json/yaml/msgpack directly from a filename instead of a
    File-like object. For YAML, ruamel.yaml must be installed. The file type is
    automatically detected. YAML is assumed if the filename contains "yaml"
    (lower or upper case). Otherwise, json is always assumed.

    Args:
        fn (str/Path): filename or pathlib.Path.
        \*args: Any of the args supported by json/yaml.load.
        \*\*kwargs: Any of the kwargs supported by json/yaml.load.

    Returns:
        (object) Result of json/yaml/msgpack.load.
    """
    if "mpk" in os.path.basename(fn).lower():
        if msgpack is None:
            raise RuntimeError(
                "Loading of message pack files is not "
                "possible as msgpack-python is not installed.")
        if "object_hook" not in kwargs:
            kwargs["object_hook"] = object_hook
        with zopen(fn, "rb") as fp:
            return msgpack.load(fp, *args, **kwargs)
    else:
        with zopen(fn) as fp:
            if "yaml" in os.path.basename(fn).lower():
                if yaml is None:
                    raise RuntimeError("Loading of YAML files is not "
                                       "possible as ruamel.yaml is not installed.")
                if "Loader" not in kwargs:
                    kwargs["Loader"] = Loader
                return yaml.load(fp, *args, **kwargs)
            else:
                if "cls" not in kwargs:
                    kwargs["cls"] = MontyDecoder
                return json.load(fp, *args, **kwargs)