Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

HaskPy - Haskell types and functions in Python

Hask is the category of types and functions in Haskell. This package provides classes and functions inspired by Hask.

Overview

Features

  • Typeclasses: Functor, Applicative, Monad, Semigroup, Monoid, Commutative, CommutativeMonoid, Foldable, Contravariant, Profunctor, Cartesian, Cocartesian

    • TODO: Traversable, Bifunctor, Monoidal
  • Types and type constructors: Identity, Maybe, Either, List, Function, Compose

    • TODO: Constant, Validation, Dictionary, LinkedList, State, Reader, Writer, IO
  • Monad transformers: MaybeT, IdentityT

    • TODO: StateT, ReaderT, WriterT, ListT
  • Simple monoids: Sum, And, Or, String, Endo

    • TODO: Product
  • Profunctor optics: adapter, lens, prism

    • TODO: traversal, grate, affine, setter
  • Operators for common tasks: ** for function composition or functorial mapping, @ for applicative application, % for monadic binding and >> for applicative/monadic sequencing.

  • Property-based testing of typeclass laws

HaskPy has implemented typeclass laws as property-based tests. Thus, one can easily test that an implementation satisfies all the laws it should. Just add something like this to your test module and run with pytest:

from haskpy.conftest import make_test_class
from mystuff import MyClass
TestMyClass = make_test_class(MyClass)

This will automatically verify that MyClass satisfies all the typeclass laws of those typeclasses that it inherits. It makes use of great Hypothesis package.

Examples

Functors

A minimal example of functorial mapping:

>>> from haskpy import map, List
>>> map(lambda x: x**2, List(1, 2, 3, 4, 5))
List(1, 4, 9, 16, 25)

Lift over two layers of functorial structure:

>>> from haskpy import map, List, Just, Nothing
>>> map(map(lambda x: x**2))(List(Just(1), Nothing, Just(3), Just(4), Nothing))
List(Just(1), Nothing, Just(9), Just(16), Nothing)

Note that haskpy.map works for all Functor instances. That is, you don't need to use a different function to lift over different functors. You can even create function that performs some operation to values contained in any two-layer functorial structure. In the following example, square squares the values inside a two-layer functor:

>>> square = map(map(lambda x: x**2))
>>> square(List(Just(1), Nothing, Just(3)))
List(Just(1), Nothing, Just(9))
>>> square(List(List(1, 2, 3), List(4, 5)))
List(List(1, 4, 9), List(16, 25))

Even functions are functors if they have been decorated with function:

>>> @function
... def f(x):
...     return List(x, 2*x, 3*x)
>>> square(f)(3)
List(9, 36, 81)

Currying

HaskPy provides curry decorator which curries a function in such a way that the function remains partially evaluated until all required arguments have been provided:

>>> from haskpy import curry
>>> @curry
... def concat(x, y, z):
...    return x + y + z
>>> concat("a")("b")("c")
"abc"
>>> concat("a")("b", "c")
"abc"

It doesn't convert the function into nested one-argument functions (as currying strictly speaking should do) but it gives more flexibility by accepting any number of arguments (even no arguments at all). It also handles keyword arguments and any other optional arguments in an intuitive way similarly as normal function calls.

It is very similar to the curry function in Toolz, but that implementation has some critical design flaws (see toolz/#471). In addition to correct behavior, the implementation of haskpy.curry is much simpler because it doesn't need to support old Python versions. Here's a bit more complex usage with keyword arguments:

>>> @curry
... def concat_with_repeat(x, y, z, r=1):
...     return r*x + r*y + r*z
>>> concat_with_repeat(r=3)("a", "b")("c")
"aaabbbccc"
>>> concat_with_repeat(y="b")("a", z="c", r=2)
"aabbcc"

Note that positional arguments can be used as keyword arguments similarly as in normal function calls.

Functions

Instead of just currying a function, you may want to convert a function into an object that has all the methods of functors, applicatives, monads and all other typeclasses a function is an instance of. In that case, you can use function decorator. Note that function also curries the function, so there's no need to use curry in addition to function.

Almost all functions in HaskPy have been decorated with function.

Copyright (C) 2019 Jaakko Luttinen

HaskPy is licensed under the MIT License. See LICENSE file for a text of the license or visit http://opensource.org/licenses/MIT.

Metadata

Release files for haskpy 0.1.2.dev20191117

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for haskpy 0.1.2.dev20191117
File Size Uploaded
haskpy-0.1.2.dev20191117.tar.gz 43.3 kB Details

Release files / haskpy-0.1.2.dev20191117.tar.gz

Download URL haskpy-0.1.2.dev20191117.tar.gz
Size 43.3 kB
Tags Source
SHA-256 checksum
How to use checksums
3245ef3164dd903ddb730b2438b8404aa85f7224997c7ee4274e9dfaecb5e2d2
BLAKE2b-256 checksum
How to use checksums
4dc3c782e450bb2d1739e699498d861a2035d243ba2831d3902f5db26b08aac9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.38.0 CPython/3.7.5

Release history Release notifications | RSS feed

0.3.0

1 release file

0.2.0

1 release file

0.1.3

1 release file

This release

0.1.0

1 release file

0.0.7

1 release file

0.0.6

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.2

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page