erg/doc/EN/syntax/17_narrowing.md
2023-03-29 22:15:39 +09:00

2 KiB

Type Narrowing

Erg allows type narrowing by conditional branching.

x: Int or NoneType
y = x + 1 # TypeError

The type of x is Int or NoneType. Because it may be None, x + 1 will cause a type error.

if x != None, do:
    x + 1 # OK
    ...

However, by checking the conditional branch to make sure that x is not None, as above, the type of x is narrowed down to Int. The isinstance function does the same thing.

if isinstance(x, Int), do:
    x + 1 # OK
    ...

Subroutines and operators that cause the narrowing effect

Currently, only the following subroutines and operators can cause the narrowing effect.

in

The expression x in T determines if x is an instance of T.

x: Int or Str
if x in Int, do:
    x + 1 # OK
    ...

notin

Has the opposite meaning of in.

isinstance

Similar to x in T, but only if the type is a simple class.

x in 1.. # OK
isinstance(x, 1..) # TypeError
isinstance(x, Int) # OK

==/is!

The expressions x == y or x is! y determine whether x is equal to y (see the API documentation for the difference between the two).

!=/isnot!

The opposite of ==/is!.

>=/>/<=/<

Refinement type methods may be used.

i: Int
if i >= 0, do:
    log i.times! # <bound method ... >

Subroutines that consume the narrowing effect

if/if!/while! causes narrowing only within the block passed as argument. If you exit the scope, the refinement is removed. For assert, narrowing occurs only within the block after the assert call.

if/if!

x: Int or Str
if x in Int, do:
    x + 1 # OK
    ...

while!

x: Int! or NoneType
while! do x != None, do!:
    x.inc!() # OK
    ...

assert

x: Int or NoneType
assert x != None
x: Int

Previous | Next