The Gleam programming language, with cat package
Introduction
The Gleam programming language targets BEAM and JavaScript. Gleam is statically typed, which has proven to be hard to live without if you're used to it. Like Gloogle, which allows you to search by types (similar to Hoogle.
Gloogle query examples -- hint: try the Filters
1 (e.g. Functions
, Documented
):
or
The cat package
The cat package implements category theory concepts in gleam. Some experimenting with the latest cat
.
The main
branch from the cat repo is used via this under [dependencies]
in gleam.toml
:
1cat = { git = "https://github.com/VSebastian8/cat.git", ref = "main" }
The code for the examples I have been experimenting with can be viewed here: photonsphere/cat_examples.
Highlights:
1import cat.{type Either, Left, Right}
2import cat/applicative as app
3import cat/bifunctor as bf
4import cat/functor.{functor_compose}
5import cat/instances/applicative as appi
6import cat/instances/bifunctor as bfi
7import cat/instances/functor as funi
8import cat/instances/monad.{Reader, Writer, fish, reader_return, writer_return}
9import cat/instances/monoid as moni
10import cat/monoid.{type Monoid, Monoid, mconcat}
11import gleam/int
12import gleam/option.{None, Some}
13import gleam/string
14
15pub fn main() {
16 // Monoid example from README (somewhat adapted).
17 let either_sum_monoid =
18 Monoid(
19 mempty: Left(0),
20 mappend: fn(e1: Either(Int, String), e2: Either(Int, String)) -> Either(
21 Int,
22 String,
23 ) {
24 case e1, e2 {
25 Right(s), _ -> Right(s)
26 _, Right(s) -> Right(s)
27 Left(a), Left(b) -> Left(a + b)
28 }
29 },
30 )
31
32 either_sum_monoid
33 |> mconcat([Left(2), Left(3), Left(4)])
34 |> echo
35 echo " ---> Left(9)"
36
37 either_sum_monoid
38 |> mconcat([Left(2), Right("error"), Left(4)])
39 |> echo
40 echo " ---> Right(\"error\")"
41
42 // Functor example from README (somewhat adapted).
43 option.Some([1, 2, 3])
44 |> functor_compose(funi.option_functor(), funi.list_functor()).fmap(fn(x) {
45 x % 2 == 0
46 })
47 |> echo
48 echo " ---> Some([False, True, False])"
49
50 // Applicative example from README (somewhat adapted).
51 [Some(1), None, Some(3)]
52 |> {
53 [fn(x) { x * 2 }, fn(x) { x + 10 }]
54 |> funi.list_functor().fmap(funi.option_functor().fmap)
55 |> app.apply(appi.list_applicative())
56 }
57 |> echo
58 echo " ---> [Some(2), None, Some(6), Some(11), None, Some(13)"
59
60 // Bifunctor examples from README (somewhat adapted)
61 // Either bifunctor
62 let either_bf = bfi.either_bifunctor()
63 // Const () functor
64 let const_f = funi.const_functor()
65 // Identity functor
66 let id_f = funi.identity_functor()
67
68 // Constructing the maybe functor:
69 // Maybe b = Either (Const () a) (Identity b)
70 let maybe_functor = fn() -> bf.Bifunctor(
71 bf.BiCompF(bfi.EitherBF, funi.ConstF(Nil), funi.IdentityF),
72 a,
73 b,
74 c,
75 d,
76 cat.Either(cat.Const(Nil, a), cat.Identity(b)),
77 cat.Either(cat.Const(Nil, c), cat.Identity(d)),
78 ) {
79 bf.bifunctor_compose(either_bf, const_f, id_f)
80 }
81
82 cat.Left(cat.Const(Nil))
83 |> maybe_functor().bimap(fn(_) { panic }, int.to_string)
84 |> echo
85 echo " ---> Left(Const(Nil)"
86
87 cat.Right(cat.Identity(3))
88 |> maybe_functor().bimap(fn(_) { panic }, int.to_string)
89 |> echo
90 echo " ---> Right(Identity(\"3\")"
91}
-
Apparently
Filters
are not available on the mobile Gloogle site ↩︎