FunML
A collection of utilities to help write python as though it were an ML-kind of functional language like OCaml.
Provides:
- Immutable data structures like enums, records, lists
- Piping outputs of one function to another as inputs. That's how bigger functions are created from smaller ones.
- Pattern matching for declarative conditional control of flow instead of using 'if's
- Error handling using the
Result
monad, courtesy of rust. Instead of usingtry-except
all over the place, functions return aResult
which has the right data when successful and an exception if unsuccessful. The result is then pattern-matched to retrieve the data or react to the exception. - No
None
. Instead, we use theOption
monad, courtesy of rust. When an Option has data, it isOption.SOME
, or else it isOption.NONE
. Pattern matching helps handle both scenarios.
Enum
Enumerable type that can only be in a limited number of forms.
Other enums are created by inheriting from this type. An enum can only be in a limited number of forms or variant and each variant can have some data associated with each instance.
Variants are created by setting class attributes. The value of the class
attributes should be the shape of the associated data or None
if variant has no
associated data.
The pre-created types of Option
and Result
are both enums
Raises:
Type | Description |
---|---|
TypeError
|
got unexpected data type, different from the signature |
Example
import funml as ml
from datetime import date
class Day(ml.Enum):
MON = date
TUE = date
WED = date
THUR = date
FRI = date
SAT = date
SUN = date
dates = [
date(200, 3, 4),
date(2009, 1, 16),
date(1993, 12, 29),
date(2004, 10, 13),
date(2020, 9, 5),
date(2004, 5, 7),
date(1228, 8, 18),
]
to_day_enum = lambda date_value: (
ml.match(date_value.weekday())
.case(0, do=lambda: Day.MON(date_value))
.case(1, do=lambda: Day.TUE(date_value))
.case(2, do=lambda: Day.WED(date_value))
.case(3, do=lambda: Day.THUR(date_value))
.case(4, do=lambda: Day.FRI(date_value))
.case(5, do=lambda: Day.SAT(date_value))
.case(6, do=lambda: Day.SUN(date_value))
)()
day_enums_transform = ml.imap(to_day_enum)
day_enums = day_enums_transform(dates)
print(day_enums)
# prints [<Day.TUE: datetime.date(200, 3, 4)>, <Day.FRI: datetime.date(2009, 1, 16)>, # <Day.WED: datetime.date(1993, 12, 29)>, <Day.WED: datetime.date(2004, 10, 13)>, # <Day.SAT: datetime.date(2020, 9, 5)>, <Day.FRI: datetime.date(2004, 5, 7)>, # <Day.FRI: datetime.date(1228, 8, 18)>]
Source code in funml/data/enum.py
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
|
name
property
The name of this Enum
value
property
The value associated with this Enum option, if any
__add_variant(name, shape=None)
classmethod
Adds a given option to the enum.
This is a chainable method that can be used to add multiple options to the same enum class.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
name |
str
|
the name of the option e.g. |
required |
shape |
Optional[Union[Type, Tuple[Type, ...], Dict[str, Type]]]
|
the signature of the associated data |
None
|
Returns:
Type | Description |
---|---|
Type[Enum]
|
the Enum class to which the option has been attached. |
Source code in funml/data/enum.py
__eq__(other)
Checks equality of the this enum and other
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
Enum
|
the value to compare with current enum. |
required |
Source code in funml/data/enum.py
__init_subclass__(**kwargs)
__str__()
_is_like(other)
See Base Class: MLType
Source code in funml/data/enum.py
generate_case(do)
See Base Class: MLType
Source code in funml/data/enum.py
IList
Bases: types.MLType
, Generic[T]
An immutable list of items of any type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
T
|
the items to be included in the list. |
()
|
Source code in funml/data/lists.py
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
|
_post_capture: List[T]
property
A slice of the list pattern after the section to be captured when matching.
_pre_capture: List[T]
property
A slice of the list pattern before the section to be captured when matching.
_self_list: List[T]
property
A cache of the native list that corresponds to this list.
_size: int
property
The number of items in the list.
head: T
property
The first item in the list.
tail: IList[T]
property
A new slice of the list containing all items except the first.
__add__(other)
Creates a new list with the current list and the other
list merged.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
IList[T]
|
the list to be appended to current list when creating new merged list. |
required |
Returns:
Type | Description |
---|---|
IList[T]
|
A new list which is a combination of the current list and the |
Raises:
Type | Description |
---|---|
TypeError
|
other is not an |
Source code in funml/data/lists.py
__eq__(other)
Checks equality of the this list and other
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
Any
|
the value to compare with current list. |
required |
__from_node(head)
classmethod
Generates a slice of the old IList given one node of that list.
In this case, the new list shares the same memory as the old list so don't use this in scenarios where immutable lists are needed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
head |
_Node[T]
|
the node from which the new list is to start from. |
required |
Returns:
Type | Description |
---|---|
IList[T]
|
A new list that shares memory with the old list. NOTE: This is not immutable. Don't use it. |
Source code in funml/data/lists.py
__getitem__(item)
Makes this list subscriptable and sliceable.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
item |
Union[slice, int]
|
the index or slice to return. |
required |
Returns:
Type | Description |
---|---|
Union[IList[T], Any]
|
An |
Raises:
Type | Description |
---|---|
IndexError
|
if |
Source code in funml/data/lists.py
__initialize_from_tuple(args)
Initializes the list using items passed to it as a tuple.
Initializes the current IList, generating nodes corresponding to the args passed
and setting any capture sections if ...
is found.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Tuple[T]
|
the items to include in the list |
required |
Source code in funml/data/lists.py
__iter__()
__len__()
__set_size_from_args(args)
Updates the size of this list basing on the args passed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Tuple[T]
|
the items to be put in this list. |
required |
__str__()
_is_like(other)
See Base Class: MLType
Source code in funml/data/lists.py
generate_case(do)
See Base class: MLType
Source code in funml/data/lists.py
Option
Bases: Enum
Represents a value that is potentially None
Variants
- SOME: when an actual value exists
- NONE: when there is no value
Example Usage
Source code in funml/data/monads.py
Result
Bases: Enum
Represents a value that is potentially an exception
Variants
- ERR: when an exception is raised
- OK: when there is a real value
Example
import funml as ml
from typing import Any
b = ml.Result.OK(60)
a = ml.Result.ERR(TypeError("some error"))
extract_result = (ml.match()
.case(ml.Result.OK(Any), do=lambda v: v)
.case(ml.Result.ERR(Exception), do=lambda v: str(v)))
extract_result(b)
# returns 60
extract_result(a)
# returns 'some error'
Source code in funml/data/monads.py
execute(*args, **kwargs)
Executes a pipeline returning its output.
A pipeline will be executed the moment this expression is reached.
Don't use >>
after a call to execute as the pipeline
would have already terminated.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
any arguments to run on the pipeline |
()
|
kwargs |
Any
|
any key-word arguments to run on the pipeline. |
{}
|
Example
Source code in funml/pipeline.py
from_json(type_, value, strict=True)
Converts a JSON string into the given type.
If strict is True, an error is returned if the JSON string cannot be converted into the type, else if strict is False and an error occurs, the default python primitive is str, dict etc. is returned.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type_ |
Type[T]
|
the typing annotation to which the JSON string is to be converted to |
required |
value |
str
|
the JSON string |
required |
strict |
bool
|
whether the JSON string should be strictly converted to the given type or left as the default primitive python objects |
True
|
Returns:
Type | Description |
---|---|
T
|
the instance got from the JSON string |
Raises:
Type | Description |
---|---|
ValueError
|
unable to deserialize JSON to given type |
Example
import funml as ml
@ml.record
class Student:
name: str
favorite_color: "Color"
@ml.record
class Color:
r: int
g: int
b: int
a: "Alpha"
class Alpha(ml.Enum):
OPAQUE = None
TRANSLUCENT = float
items = [
(
ml.IList[Color],
(
"["
'{"name": "John Doe", "favorite_color": {"r": 8, "g": 4, "b": 78, "a": "Alpha.OPAQUE: \"OPAQUE\""}}, '
'{"name": "Jane Doe", "favorite_color": {"r": 55, "g": 40, "b": 9, "a": "Alpha.TRANSLUCENT: 0.4"}}'
"]"
)
),
(Color, '{"r": 55, "g": 40, "b": 9, "a": "Alpha.TRANSLUCENT: 0.4"}'),
(Alpha, "Alpha.TRANSLUCENT: 0.4"),
]
# setting strict to False can allow any json string to be converted to a python object,
# first attempting to convert it to the provided type, and if it fails,
# the output of an ordinary json.loads call is returned.
#
# However, when strict is True, ValueError's will be raised
# if the json string can't be converted into the given type
strict = True
for type_, item_json in items:
item = ml.from_json(type_=type_, value=item_json, strict=strict)
print(item)
Source code in funml/json.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
|
if_err(do, strict=True)
Does the given operation if value passed to resulting expression is Result.ERR.
If the value is Result.OK, it just returns the Result.OK without doing anything about it.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
do |
Union[Expression, Callable, Any]
|
The expression, function, to run or value to return when Result.ERR |
required |
strict |
bool
|
if only Results should be expected |
True
|
Example
import funml as ml
ok_value = ml.Result.OK(90)
err_value = ml.Result.ERR(TypeError("some stuff"))
another_value = None
# in case the value may not be a Result, set strict to False
print(ml.if_err(str, strict=False)(another_value))
# prints None
err_to_str = ml.if_err(str)
print(err_to_str(err_value))
# prints 'some stuff'
print(err_to_str(ok_value))
# prints <Result.OK: ('90',)>
Returns:
Type | Description |
---|---|
Expression
|
An expression to run the |
Expression
|
or to just return the Result.OK |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not a Result if strict is True |
Source code in funml/data/monads.py
if_none(do, strict=True)
Does the given operation if value passed to resulting expression is Option.NONE.
If the value is Option.SOME, it just returns the Option.SOME without doing anything about it.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
do |
Union[Expression, Callable, Any]
|
The expression, function, to run or value to return when Option.NONE |
required |
strict |
bool
|
if only Options should be expected |
True
|
Example
import funml as ml
some_value = ml.Option.SOME(90)
none_value = ml.Option.NONE
another_value = None
# in case the value may not be an Option, set strict to False
print(ml.if_none(str, strict=False)(another_value))
# prints None
none_to_str = ml.if_none(str)
print(none_to_str(some_value))
# prints <Option.SOME: (90,)>
print(none_to_str(none_value))
# prints ('NONE',)
Returns:
Type | Description |
---|---|
Expression
|
An expression to run the |
Expression
|
or to just return the Option.SOME |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not an Option if strict is True |
Source code in funml/data/monads.py
if_ok(do, strict=True)
Does the given operation if value passed to resulting expression is Result.OK.
If the value is Result.ERR, it just returns the Result.ERR without doing anything about it.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
do |
Union[Expression, Callable, Any]
|
The expression, function to run or value to return when Result.OK |
required |
strict |
bool
|
if only Results should be expected |
True
|
Example
import funml as ml
ok_value = ml.Result.OK(90)
err_value = ml.Result.ERR(TypeError("some stuff"))
another_value = None
# in case the value may not be a Result, set strict to False
print(ml.if_ok(str, strict=False)(another_value))
# prints None
ok_to_str = ml.if_ok(str)
print(ok_to_str(err_value))
# prints <Result.ERR: (TypeError('some stuff'),)>
print(ok_to_str(ok_value))
# prints 90
Returns:
Type | Description |
---|---|
Expression
|
An expression to run the |
Expression
|
or to just return the Result.ERR |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not a Result and |
Source code in funml/data/monads.py
if_some(do, strict=True)
Does the given operation if value passed to resulting expression is Option.SOME.
If the value is Result.NONE, it just returns the Result.NONE without doing anything about it.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
do |
Union[Expression, Callable, Any]
|
The expression, function, to run or value to return when Option.SOME |
required |
strict |
bool
|
if only Options should be expected |
True
|
Example
import funml as ml
some_value = ml.Option.SOME(90)
none_value = ml.Option.NONE
another_value = None
# in case the value may not be an Option, set strict to False
print(ml.if_some(str, strict=False)(another_value))
# prints None
some_to_str = ml.if_some(str)
print(some_to_str(some_value))
# prints 90
print(some_to_str(none_value))
# prints <Option.NONE: ('NONE',)>
Returns:
Type | Description |
---|---|
Expression
|
An expression to run the |
Expression
|
or to just return the Option.NONE |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not an Option if strict is True |
Source code in funml/data/monads.py
ifilter(func)
Creates an expression to transform each item by the given function.
Expressions can be computed lazily at any time.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Callable[[Any], Any]
|
the function to use to check if item should remain or be ignored. |
required |
Returns:
Type | Description |
---|---|
Expression
|
A new iList with only the items of data that returned true when |
Source code in funml/data/lists.py
imap(func)
Creates an expression to transform each item by the given function.
Expressions can be computed lazily at any time.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Callable[[Any], Any]
|
the function to use to transform each item |
required |
Returns:
Type | Description |
---|---|
Expression
|
A new IList with each item in data transformed according to the |
Source code in funml/data/lists.py
ireduce(func, initial=None)
Creates an expression to reduce a sequence into one value using the given func
.
Expressions can be computed lazily at any time.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Callable[[Any, Any], Any]
|
the function to reduce the sequence into a single value. |
required |
initial |
Optional[Any]
|
the initial value that acts like a default when sequence is empty,
and is added onto by |
None
|
Returns:
Type | Description |
---|---|
Expression
|
A single item got from calling |
Expression
|
two adjacent items. |
Source code in funml/data/lists.py
is_err(v, strict=True)
Checks if v
is Result.ERR.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Result
|
The value to check |
required |
strict |
bool
|
if value should be a Result |
True
|
Example
import funml as ml
ok_value = ml.Result.OK(90)
err_value = ml.Result.ERR(TypeError())
print(ml.is_err(ok_value))
# prints False
print(ml.is_err(err_value))
# prints True
another_value = None
# in case the value is not always a Result, set `strict` to False
# to avoid a MatchError
print(ml.is_err(another_value, strict=False))
# prints False
Returns:
Type | Description |
---|---|
bool
|
True if |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not a Result if strict is True |
Source code in funml/data/monads.py
is_none(v, strict=True)
Checks if v
is Option.NONE.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Option
|
The value to check |
required |
strict |
bool
|
if value should be a Option |
True
|
Example
import funml as ml
some_value = ml.Option.SOME(90)
none_value = ml.Option.NONE
print(ml.is_none(some_value))
# prints False
print(ml.is_none(none_value))
# prints True
another_value = None
# in case the value is not always an Option, set `strict` to False
# to avoid a MatchError
print(ml.is_none(another_value, strict=False))
# prints False
Returns:
Type | Description |
---|---|
bool
|
True if |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not an Option if strict is True |
Source code in funml/data/monads.py
is_ok(v, strict=True)
Checks if v
is Result.OK.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Result
|
The value to check |
required |
strict |
bool
|
if value should be a Result |
True
|
Example
import funml as ml
ok_value = ml.Result.OK(90)
err_value = ml.Result.ERR(TypeError())
print(ml.is_ok(ok_value))
# prints True
print(ml.is_ok(err_value))
# prints False
another_value = None
# in case the value is not always a Result, set `strict` to False
# to avoid a MatchError
print(ml.is_ok(another_value, strict=False))
# prints False
Returns:
Type | Description |
---|---|
bool
|
True if |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not a Result if strict is True |
Source code in funml/data/monads.py
is_some(v, strict=True)
Checks if v
is Option.SOME.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Option
|
The value to check |
required |
strict |
bool
|
if value should be a Option |
True
|
Example
import funml as ml
some_value = ml.Option.SOME(90)
none_value = ml.Option.NONE
print(ml.is_some(some_value))
# prints True
print(ml.is_some(none_value))
# prints False
another_value = None
# in case the value is not always an Option, set `strict` to False
# to avoid a MatchError
print(ml.is_some(another_value, strict=False))
# prints False
Returns:
Type | Description |
---|---|
bool
|
True if |
Raises:
Type | Description |
---|---|
funml.errors.MatchError
|
value provided was not an Option if strict is True |
Source code in funml/data/monads.py
l(*args)
Creates an immutable list of any type of items.
Creates a list of items of any type, that cannot be changed once created. It can only be used to create other lists, using methods on it like
+
- to combine two separate lists into a new one containing elements of bothimap(fn)
- to create a new list with each element transformed according to the given functionfn
filter(fn)
- to return a new list containing only elements that conform to the given functionfn
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
the items that make up the list |
()
|
Returns:
Type | Description |
---|---|
IList
|
An immutable list, `IList, containing the items passed to it. |
Example
import funml as ml
items = ml.l(120, 13, 40, 60, "hey", "men")
# or items = ml.l(item for item in values) where values is an iterable
num_filter = ml.ifilter(lambda x: isinstance(x, (int, float)))
str_filter = ml.ifilter(lambda x: isinstance(x, str))
nums = num_filter(items)
strings = str_filter(items)
double_transform = ml.imap(lambda x: x*2)
doubled_nums = double_transform(nums)
aggregator = ml.ireduce(lambda x, y: f"{x}, {y}")
list_as_str = aggregator(items)
print(nums)
# prints [120, 13, 40, 60]
print(strings)
# prints ["hey", "men"]
print(doubled_nums)
# prints [240, 26, 80, 120]
print(list_as_str)
# prints '120, 13, 40, 60, hey, men'
Source code in funml/data/lists.py
match(arg=None)
Matches the argument with a corresponding case, and calls it do
operation.
It runs through a range of cases, looking for any that match
the current arg. If it finds it, it calls the do
operation attached
to that case.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
arg |
Optional[Any]
|
the argument which is to be checked against the list of patterns. |
None
|
Returns:
Type | Description |
---|---|
MatchExpression
|
A |
Raises:
Type | Description |
---|---|
MatchError
|
failed to find a match for the argument. |
Example
import funml as ml
@ml.record
class Color:
r: int
g: int
b: int
raw_value = ml.Option.SOME(90)
value = (
ml.match(raw_value)
.case(ml.Option.SOME(int), do=lambda v: v + 6)
.case(ml.Option.NONE, do=lambda: "nothing to show")
.case(Color(red=255), do=lambda v: v.red + v.green)
.case(ml.l(..., 5), do=lambda v: v)
.case(ml.l(8, 5, ...), do=lambda v: str(v))
)()
print(value)
# prints 96
Source code in funml/pattern_match.py
record(cls)
Creates a Schema type to create similar records.
Used usually as a decorator inplace of @dataclass on dataclass-like classes to make them ml-functional.
It creates a Schema for similar objects that contain a given
set of attributes. For example, it can create a Book
schema
whose attributes include author
, title
, isbn
etc.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cls |
Type[R]
|
the class to transform into a record |
required |
Returns:
Type | Description |
---|---|
Type[R]
|
A class which can act as a record of the particular schema set by the attributes. |
Example
Source code in funml/data/records.py
to_dict(v)
Converts a record into a dictionary.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Record
|
the |
required |
Returns:
Type | Description |
---|---|
Dict[str, Any]
|
the dictionary representation of the record |
Example
import funml as ml
@ml.record
class Department:
seniors: list[str]
juniors: List[str]
locations: tuple[str, ...]
misc: dict[str, Any]
head: str
sc_dept = Department(
seniors=["Joe", "Jane"],
juniors=["Herbert", "Leo"],
locations=("Kasasa", "Bujumbura", "Bugahya"),
misc={"short_name": "ScDept"},
head="John",
)
data = ml.to_dict(sc_dept)
print(data)
Source code in funml/data/records.py
to_json(value)
Converts the type into a JSON string.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any
|
the value to convert to a JSON string |
required |
Returns:
Type | Description |
---|---|
str
|
the JSON string representation of this instance |
Example
import funml as ml
@ml.record
class Student:
name: str
favorite_color: "Color"
@ml.record
class Color:
r: int
g: int
b: int
a: "Alpha"
class Alpha(ml.Enum):
OPAQUE = None
TRANSLUCENT = float
items = [
ml.l(
True,
Color(r=8, g=4, b=78, a=Alpha.OPAQUE),
Color(r=55, g=40, b=9, a=Alpha.TRANSLUCENT(0.4)),
),
Color(r=8, g=4, b=78, a=Alpha.OPAQUE),
Alpha.TRANSLUCENT(0.4),
]
for item in items:
item_json = ml.to_json(item)
print(item_json)
Source code in funml/json.py
val(v)
Converts a generic value or lambda expression into a functional expression.
This is useful when one needs to use piping on a non-ml function or value. It is like the connection that give non-ml values and functions capabilities to be used in the ml world.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v |
Union[Expression, Callable, Any]
|
the value e.g. 90 or function e.g. |
required |
Returns:
Type | Description |
---|---|
Expression
|
an ml |
Example
Source code in funml/expressions.py
Types
All types used by funml
Pipeline
A series of logic blocks that operate on the same data in sequence.
This has internal state so it is not be used in such stuff as recursion. However when compile is run on it, a reusable (pure) expression is created.
Source code in funml/types.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
|
__as_async()
__call__(*args, **kwargs)
Computes the logic within the pipeline and returns the value.
This method runs all those expressions in the queue sequentially, with the output of an expression being used as input for the next expression.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
any arguments passed. |
()
|
kwargs |
Any
|
any key-word arguments passed |
{}
|
Returns:
Type | Description |
---|---|
Union[Expression, Awaitable[Expression], Awaitable[Any], Any]
|
the computed output of this pipeline or a partial expression if the args and kwargs provided are less than those expected. |
Source code in funml/types.py
__copy__()
__rshift__(nxt)
Uses >>
to append the nxt expression, callable, pipeline to this pipeline.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
nxt |
Union[Expression, Callable, Pipeline]
|
the next expression, pipeline, or callable to apply after the current one. |
required |
Returns:
Type | Description |
---|---|
Union[Pipeline, Any]
|
the updated pipeline or the value when the pipeline is executed in case |
Raises:
Type | Description |
---|---|
ValueError
|
when the pipeline is already terminated with ml.execute() in its queue. |
Source code in funml/types.py
__update_queue(nxt)
Appends a pipeline or an expression to the queue.
Source code in funml/types.py
AsyncPipeline
Bases: Pipeline
A pipeline for handling async code.
See more details in the base class
Source code in funml/types.py
__call__(*args, **kwargs)
async
Computes the logic within the pipeline and returns the value.
This method runs all those expressions in the queue sequentially, with the output of an expression being used as input for the next expression.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
any arguments passed. |
()
|
kwargs |
Any
|
any key-word arguments passed |
{}
|
Returns:
Type | Description |
---|---|
Union[Expression, Any]
|
the computed output of this pipeline or a partial expression if the args and kwargs provided are less than expected. |
Source code in funml/types.py
Expression
Logic that returns a value when applied.
This is the basic building block of all functions and thus almost everything in FunML is converted into an expression at one point or another.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
f |
Optional[Operation]
|
the operation or logic to run as part of this expression |
None
|
Source code in funml/types.py
__call__(*args, **kwargs)
Computes the logic within and returns the value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
any arguments passed. |
()
|
kwargs |
Any
|
any key-word arguments passed |
{}
|
Returns:
Type | Description |
---|---|
Union[Expression, Any]
|
the computed output of this expression or another expression with a partial operation in it if the args provided are less than expected. |
Source code in funml/types.py
__rshift__(nxt)
This makes piping using the '>>' symbol possible.
Combines with the given nxt
expression or pipeline to produce a new pipeline
where data flows from current to nxt.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
nxt |
Union[Expression, Pipeline, Callable]
|
the next expression, pipeline, or callable to apply after the current one. |
required |
Returns:
Type | Description |
---|---|
Union[Pipeline, Any]
|
a new pipeline where the first expression is the current expression followed by |
Source code in funml/types.py
ExecutionExpression
Bases: Expression
Expression that executes all previous once it is found on a pipeline
Raises:
Type | Description |
---|---|
NotImplementedError
|
when |
Source code in funml/types.py
__rshift__(nxt)
rshift is not supported for this.
This is a terminal expression that expects no other expression after it on the pipeline.
MatchExpression
Bases: Expression
A special expression used when pattern matching.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
arg |
Optional[Any]
|
the value to be pattern matched. |
None
|
Source code in funml/types.py
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
|
__add_match(check, expn)
Adds a match set to the list of match sets
A match set comprises a checker function and an expression. The checker function checks if a given argument matches this case. The expression is called when the case is matched.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
check |
Callable[[Any], bool]
|
the checker function |
required |
expn |
Expression
|
the expression to run if a value matches. |
required |
Source code in funml/types.py
__call__(arg=None)
Applies the matched case and returns the output.
The match cases are surveyed for any that matches the given argument until one that matches is found. Then the expression of that case is run and its output returned.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
arg |
Optional[Any]
|
the potential value to match against. |
None
|
Returns:
Type | Description |
---|---|
Union[Expression, Any]
|
The output of the expression of the matched case. |
Raises:
Type | Description |
---|---|
MatchError
|
no case was matched for the given argument. |
Source code in funml/types.py
case(pattern, do)
Adds a case to a match statement.
This is chainable, allowing multiple cases to be added to the same match pipeline.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pattern |
Union[MLType, Any]
|
the pattern to match against. |
required |
do |
Callable
|
the logic to run if pattern is matched. |
required |
Returns:
Type | Description |
---|---|
MatchExpression
|
The current match expressions, after adding the case. |
Source code in funml/types.py
MLType
An ML-enabled type, that can easily be used in pattern matching, piping etc.
Methods common to ML-enabled types are defined in this class.
Source code in funml/types.py
generate_case(do)
Generates a case statement for pattern matching.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
do |
Operation
|
The operation to do if the arg matches on this type |
required |
Returns:
Type | Description |
---|---|
Tuple[Callable[[Any], bool], Expression]
|
A tuple (checker, expn) where checker is a function that checks if argument matches this case, and expn is the expression that is called when the case is matched. |
Source code in funml/types.py
Operation
A computation.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
func |
Callable
|
the logic to run as part of the operation. |
required |
Source code in funml/types.py
__call__(*args, **kwargs)
Applies the logic attached to this operation and returns output.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
args |
Any
|
the args passed |
()
|
kwargs |
Any
|
the context in which the operation is being run. |
{}
|
Returns:
Type | Description |
---|---|
Union[Operation, Any]
|
the final output of the operation's logic code or a partial operation if the args and kwargs provided are less than those expected. |