<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def hash_file(path: str, progress_callback: Callable[[float], None], chunk_size: int = 1024, file_size: int = None, algo: str = 'sha256') -> bytes: """ Hash a file and return the hash, providing progress callbacks :param path: The file to hash :param progress_callback: The callback to call with progress between 0 and 1. May not ever be precisely 1.0. :param chunk_size: If specified, the size of the chunks to hash in one call If not specified, defaults to 1024 :param file_size: If specified, the size of the file to hash (used for progress callback generation). If not specified, calculated internally. :param algo: The algorithm to use. Can be anything used by :py:mod:`hashlib` :returns: The output has ascii hex """

    hasher = hashlib.new(algo)
    have_read = 0
    if not chunk_size:
        chunk_size = 1024
    with open(path, 'rb') as to_hash:
        if not file_size:
            file_size = to_hash.seek(0, 2)
            to_hash.seek(0)
        while True:
            chunk = to_hash.read(chunk_size)
            hasher.update(chunk)
            have_read += len(chunk)
            progress_callback(have_read/file_size)
            if len(chunk) != chunk_size:
                break
    return binascii.hexlify(hasher.digest())