# Tools and Utilities for 'compiling' trees of `Dynamic` functions into statically typed values
This package consists of two modules: `Data.Dynamic.Resolve.Utils` that contains various utility functions for working with [Data.Dynamic](http://hackage.haskell.org/package/base4.12.0.0/docs/DataDynamic.html)'s `Dynamic`s (particularly for dealing with `Monad`s, `Functor`s, and `Applicative`s), and `Data.Dynamic.Resolve`, which contains higherlevel functions for applying chains of `Dynamic`wrapped functions safely, with good error information, and with support for multiple possible values for a given parameter. This readme will focus on the latter.
## Quick Notes
Many functions in this library have a type variable `env` that is not used within the rest of the type signature (because it is swallowed by the `Dynamic`s) and so cannot be inferred by GHC. The easiest way to specify it is with the [`TypeApplications` extension](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extensionTypeApplications). `env` is a monad representing the 'environment' that your functions should be resolved in, and is used to allow pure and monadic values of the specified type to be fed into one another without explicit `bind`s. This is useful for, for example, evaluating a language that can do IO, and doesn't share Haskell's level of separation of effects. If this is undesirable, pure versions are also provided (which usually simply use `Identity` for `env`).
## Usage Overview
1. Make whatever type you're using to carry around your `Dynamics` an instance of `Parameter`, which requires a `values` function which returns a `NonEmpty` list of `Dynamics`, representing the possible values of that parameter.
2. For simple usage, invoke `reifyList `. It will return `Either` information about where the chain of function application failed, or the desired type.
3. For more advanced usage, build a `Tree` of function application and use `reifyTree`. Application trees are evaluated by first evaluating fully the left and right subtrees of a given branch, and then applying the result of the left subtree to the result of the right subtree. Here are some examples of function applications and their corresponding application trees (note that in actual code, the values would be wrapped inside `Parameter`s):
(+) 1 2
```
(+) :*: 1 :*: 2
+ 2

++ 1

+ (+)
```
(+) 1 ((+) 2 3)
```
(+) :*: 1 :*: ((+) :*: 1 :*: 2)
++ 3
 
 ++ 2
 
 + (+)

++ 1

+ (+)
```
3argfn 1 2 3
```
3argfn :*: 1 :*: 2 :*: 3
+ 3

++ 2

++ 1

+ 3argfn
```