# Path: pyknow/fieldconstraint.py
# class P(Bindable, FieldConstraint):
#     """Predicate Field Constraint"""
#     def __new__(cls, match, __bind__=None):
#         if not isinstance(match, Callable):
#             raise TypeError("PredicateFC needs a callable.")
#         else:
#             obj = super(P, cls).__new__(cls, match)
#             obj.__bind__ = __bind__
#             return obj
# 
#     @property
#     def match(self):
#         return self[0]


from functools import singledispatch
from frozendict import frozendict
from .fieldconstraint import P
import collections.abc




class frozenlist(tuple):
    def __repr__(self):
        return "frozenlist([%s])" % (super().__repr__()[1:-1], )


@singledispatch
def freeze(obj):
    if isinstance(obj, collections.abc.Hashable):
        return obj
    else:
        raise TypeError(
            ("type(%r) => %s is not hashable, "
             "see `pyknow.utils.freeze` docs to register your "
             "own freeze method") % (obj, type(obj)))


@freeze.register(dict)
@freeze.register(frozendict)
def freeze_dict(obj):

# Path: pyknow/fieldconstraint.py
# class P(Bindable, FieldConstraint):
#     """Predicate Field Constraint"""
#     def __new__(cls, match, __bind__=None):
#         if not isinstance(match, Callable):
#             raise TypeError("PredicateFC needs a callable.")
#         else:
#             obj = super(P, cls).__new__(cls, match)
#             obj.__bind__ = __bind__
#             return obj
# 
#     @property
#     def match(self):
#         return self[0]


# Path: pyknow/utils.py
from functools import singledispatch
from frozendict import frozendict
from .fieldconstraint import P
import collections.abc





class frozenlist(tuple):
    def __repr__(self):
        return "frozenlist([%s])" % (super().__repr__()[1:-1], )


@singledispatch
def freeze(obj):
    if isinstance(obj, collections.abc.Hashable):
        return obj
    else:
        raise TypeError(
            ("type(%r) => %s is not hashable, "
             "see `pyknow.utils.freeze` docs to register your "
             "own freeze method") % (obj, type(obj)))


@freeze.register(dict)
@freeze.register(frozendict)
def freeze_dict(obj):

    return frozendict((k, freeze(v)) for k, v in obj.items())