Container Types
Opshin has two main container types:
List[a]
Dict[k, v]
Note: The container types are generic, and the letter in square brackets (
[]
) are the type arguments
List[a]
The Opshin List
type is a container type that is used to hold multiple values of the same type.
This is works just like the list
type in Python.
listy: List[int] = [1, 2, 3, 4, 5]
Note: Opshin lists are actually linked-lists. This is because that's how lists are implemented in UPLC.
List Operations
You can add lists using the +
operator.
print([1, 2, 3, 4] + [5, 6])
# prints "[1, 2, 3, 4, 5, 6]"
List Access
You may access elements at arbitrary positions within a list like this:
listy[3] # will return the element at the 4th position (3rd with 0-based indexing), i.e. 4
If you want to count from the back, use negative numbers:
listy[-2] # returns the second-to-last element, i.e. 4
List Slices
You may access slices of a list using the slicing syntax.
["a", "b", "c", "d"][1:3] # returns ["b", "c"]
List Comprehension
Opshin supports Python's list comprehension syntax. This allows for very compact list initialization:
squares = [x**2 for x in listy]
len(x)
The len
method returns the length of the list as an int
:
lenny: int = len(listy)
lenny == 5 # True
Membership using in
You can check whether some element is included in a list of elements using the keyword in
.
4 in [1, 2, 3, 4, 5] # True
100 in range(10) # False
Empty lists
Empty lists may only be created in annotated assignments. This is to ensure that the type of the empty list can be correctly inferred.
a = [] # Fails! Unclear what type this expression has!
a: List[int] = [] # This works!
Dict[k, v]
The Dict
type represents a map from keys of type k
to values of type v
.
It works just like the dict
type in Python.
# A dictionary storing scores in a game.
scores: Dict[str, int] = {"god_binder": 12, "radio_knight": 42}
Dictionary Access
A dictionary implements a map. In order to find the mapped value of element x
we can
access it in the dictionary via dict[x]
.
scores["god_binder"] # returns 12
Take care when accessing values that are not contained in the dictionary - in case of missing keys, the contract will fail immediately.
scores["peter_pan"] # fails with "KeyError"
If you are not sure whether a key maps to something in the dictionary
use dict.get(x, d)
. It will try to return the value mapped to by x
in the dictionary.
If x
is not present it will return d
.
It is important that
d
is of the value typev
to guarantee type safety.
scores.get("god_binder", 0) # returns 12
scores.get("peter_pan", 0) # returns 0
.keys()
The .keys()
method returns a list of the keys in a dictionary,
players: List[str] = scores.keys() # ["god_binder", "radio_knight"]
.values()
The .values()
method returns a list of all the values in a dictionary.
raw_scores: List[int] = scores.values() # [12, 42]
.items()
The .items()
method returns a tuple of the each key-value pair in the dictionary.
This is particularly useful if you want to iterate over all pairs contained in a dictionary.
for username, score in scores.items():
print(f"{username} scored: {score}")
# prints first "god_binder scored: 12" and then "radio_knight scored: 42"