Depending on what you're trying to accomplish, you may find the relation/composition <https://docs.racket-lang.org/relation/Composing_Operations.html> module (which I authored) to be of interest. It doesn't model algebraic structures explicitly but uses them to generalize common composition operators like + (as a group), and .. (as a monoid). It also provides derived functions like power <https://docs.racket-lang.org/relation/Composing_Operations.html#%28def._%28%28lib._relation%2Fcomposition..rkt%29._power%29%29> .
If this is the kind of thing you're trying to do, also take a look at generic interfaces <https://docs.racket-lang.org/reference/struct-generics.html> (used in the above library) which resemble typeclasses, and which could be used to define monoids, groups, and so on as interfaces, which particular Racket types could implement. There's also the Algebraic Racket <https://docs.racket-lang.org/algebraic/class_base.html> library which I believe uses classes and objects rather than generic interfaces, and has a lot of other algebraic goodies as far as I can tell. On Wed, Jan 20, 2021 at 3:22 PM Jens Axel Søgaard <jensa...@soegaard.net> wrote: > Den ons. 20. jan. 2021 kl. 08.43 skrev Stuart Hungerford < > stuart.hungerf...@gmail.com>: > >> On Wednesday, 20 January 2021 at 12:34:59 UTC+11 Robby Findler wrote: >> >> I'm no expert on algebras, but I think the way to work on this is not to >>> think "what Racket constructs are close that I might coopt to express what >>> I want?" but instead to think "what do I want my programs to look like" and >>> then design the language from there, reusing libraries as they seem helpful >>> or designing new ones that do what you want. Racket's >>> language-implementation facilities are pretty powerful (of course, if there >>> is nothing like what you end up needing, there will still be actual >>> programming to do ;). >>> >> >> Thanks Robby -- that's a very interesting way to look at library design >> that seems to make particular sense in the Racket environment. >> > > An example of such an approach is racket-cas, a simple general purpose > cas, which > represents expressions as s-expression. > > The polynomial 4x^2 + 3 is represented as '(+ 3 (* 4 (expt x 2))) > internally. > > The expressions are manipulated through pattern matching. Instead of > using the standard `match`, I wanted my own version `math-match`. > The idea is that `math-match` introduces the following conventions in > patterns: > > prefix x y z will match symbols only > prefix r s will match numbers only (not bigfloats) > prefix p q wil match exact naturals only > prefix 𝛼 𝛽 will match exact numbers > prefix bool will match booleans only > > suffix .0 will match inexact numbers only > suffix .bf will match bigfloats only > > As an example, here is the part that implements the symbolic natural > logarithm > (the assumption is that the argument u is in normalized form): > > (define (Ln: u) > (math-match u > [1 0] ; ln(1)=0 > [r. #:when (%positive? r.) (%ln r.)] ; here %ln is an ln > that handles both reals and bigfloats > [@e 1] ; @e is the syntax > matching Euler's e, ln(e)=1 > [(Complex a b) #:when (not (equal? 0 b)) ; all complex numbers > are handled here > (⊕ (Ln (Sqrt (⊕ (Sqr a) (Sqr b)))) > (⊗ @i (Angle (Complex a b))))] > [(Expt @e v) v] ; ln(e^v) = v > [(Expt u α) #:when (= (%numerator (abs α)) 1) ; ln( u^(/n) ) = 1/n > ln(u) > (⊗ α (Ln: u))] > [(⊗ u v) (⊕ (Ln: u) (Ln: v))] ; ln(u*v) = ln(u) + > ln(v) > [_ `(ln ,u)])) ; keep as is > > Note that the match pattern (⊗ u v) matches not only products of two > factors, but general products. > Matching (⊗ u v) agains (* 2 x y z) will bind u to 2 and v to (* x y z). > This convention turned out to be very convenient. > > I am happy about many aspects of racket-cas, but I wish I used structs to > represent the expressions. > Thanks to the custom matcher, it ought to be possible to change the > underlying representation > and still reuse most parts of the code. That's a future project. > > > Back to your project - what is the goal of the project? > Making something like GAP perhaps? > Do you want your users to supply types - or do you want to go a more > dynamic route? > > /Jens Axel > > > > > > > > > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/racket-users/CABefVgwbdetq%2BWBa4h6MPLt1XxnhFQSiOACPC46xsx6cVA9imQ%40mail.gmail.com > <https://groups.google.com/d/msgid/racket-users/CABefVgwbdetq%2BWBa4h6MPLt1XxnhFQSiOACPC46xsx6cVA9imQ%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/CACQBWFnNwcC2AheYtEt20fUobW3%2BraB3T%2BECTrrhAfnca2p0Bg%40mail.gmail.com.