import typing
Ninf = typing.Callable[[int], bool]
Ninf_map = typing.Callable[[Ninf], bool]
def omniscience(p : Ninf_map) -> typing.Optional[Ninf]:
print("success")
How can I make this say "success"?
CodePudding user response:
Just call the function omniscience with an argument
omniscience(1)
CodePudding user response:
The simple answer is "call omniscience
with an appropriate argument". At runtime, p
can be anything, since you don't actually use it. If you are performing static type-checking, p
has to be a function (or more precisely, something you can call), even though p
is never called or used. (Type checkers only worry about matching signatures, not about runtime behavior.)
Let's look at Ninf
: it's basically a predicate on integers. Some examples might be named even
, odd
, greater_than_zero
, etc. It takes a number, and returns True
or False
based on some property of the number.
Let's take a look at Ninf_map
. It's another predicate, but this time on a predicate itself. We're at a level of abstraction that's a little harder to grasp. What kind of predicates can we define on a predicate? We can't really "examine" the predicate; all we can do is call it on some arguments and see what it returns in each case
Here's a trivial example.
# satisfiable has type Ninf_map. It will return
# true if there is *some* number n for which p(n) is true.
def statisfiable(p: Ninf) -> bool:
if p(0):
return True
for n in count(1):
if p(n) or p(-n):
return True
return False
(Note that satisfiable
can never return False
; it either returns True
or it runs forever. But, the type is OK, which is all we care about here.)
Because satisfiable
has type Callable[[Ninf],bool]
, it is a valid argument to omniscience
, regardless of whether omniscience
uses it or not.
omniscience(satisfiable) # This type checks; satisfiable has the correct type.