-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathexample0001-polynomials.lhs
68 lines (52 loc) · 2.48 KB
/
example0001-polynomials.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
This first example shows how to use polynomials.
It should give you a taste of using categories for numerical applications.
First, some preliminaries:
> {-# LANGUAGE NoImplicitPrelude #-}
> {-# LANGUAGE RebindableSyntax #-}
> import SubHask
> import SubHask.Category.Polynomial
> import System.IO
We'll do everything within the `main` function so we can print some output as we go.
> main = do
To start off, we'll just create an ordinary function and print it's output.
The `Ring` class below corresponds very closely with the Prelude's `Num` class.
> let f :: Ring x => x -> x
> f x = x*x*x + x + 3
>
> let a = 3 :: Integer
>
> putStrLn $ "f a = " + show (f a)
Now, we'll create a polynomial from our ordinary function.
> let g :: Polynomial Integer
> g = provePolynomial f
>
> putStrLn ""
> putStrLn $ "g $ a = " + show ( g $ a )
The function `provePolynomial` above gives us a safe way to convert an arrow in Hask into an arrow in the category of polynomials.
The implementation uses a trick similar to automatic differentiation.
In general, every `Concrete` category has at least one similar function.
Finally, in order to apply our polynomial to a value, we must first convert it back into an arrow in Hask.
The function application operator `$` performs this task for us.
Polynomials support operations that other functions in Hask do not support.
For example, we can show the value of a polynomial:
> putStrLn ""
> putStrLn $ "g = " + show g
> putStrLn $ "g*g+g = " + show (g*g + g)
Polynomials also support decidable equality:
> putStrLn ""
> putStrLn $ "g==g = " + show (g==g)
> putStrLn $ "g==g*g+g = " + show (g==g*g+g)
Finally, we can create polynomials of polynomials:
> let h :: Polynomial (Polynomial Integer)
> h = provePolynomial f
>
> putStrLn ""
> putStrLn $ " h = " + show h
> putStrLn $ " h $ g = " + show ( h $ g )
> putStrLn $ "(h $ g) $ a = " + show (( h $ g ) $ a)
**For advanced readers:**
You may have noticed that function application on polynomials is equivalent to the join operation on monads.
That's because polynomials form a monad on Hask.
Sadly, we can't make `Polynomial` an instance of the new `Monad` class due to some limitatiions in GHC's type system.
This isn't too big of a loss though because I don't know of a useful application for this particular monad.
The monad described above is different than what category theorists call polynomial monads (see: http://ncatlab.org/nlab/show/polynomial+functor).