File: add_function.md

package info (click to toggle)
bali-phy 4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 15,392 kB
  • sloc: cpp: 120,442; xml: 13,966; haskell: 9,975; python: 2,936; yacc: 1,328; perl: 1,169; lex: 912; sh: 343; makefile: 26
file content (93 lines) | stat: -rw-r--r-- 3,372 bytes parent folder | download | duplicates (2)
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
% Adding a function to BAli-Phy

Since BAli-Phy models are written in Haskell, you can define functions
inside your own model file.  However, some functions are used frequently
enough to add them to BAli-Phy itself instead of including them
separately in multiple different model files.

Adding a function to BAli-Phy involves adding it to one of the Haskell
modules that comes with BAli-Phy so that it can be used from multiple
different model files.  To make the function visible from the 
command line as well, you will need to add a JSON file to the `bindings`
directory that describes how to access the Haskell function.

## Haskell modules

In order to add a function to BAli-Phy you need to add it to a module.
For example, if you add the function to the module
`SModel.Nucleotides` then you could access it by adding
```Haskell
import SModel.Nucleotides
```
to the beginning of your model file.

The Haskell file for the module `SModel.Nucleotides` is located at
`haskell/SModel/Nucleotides.hs`. (See the [haskell/](https://github.com/bredelings/BAli-Phy/blob/master/haskell/) 
directory on github.) The module file begins with a 
module declaration:

```Haskell
module SModel.Nucleotides where
```

We can then write a function inside this module.  For example, in the module
`SModel.Nucleotides`, we have the function `hky85`:
```Haskell
hky85 k    pi a = gtr a (hky85_sym k a) pi
```
This function defines the `hky85` model as a function of the
transition-transversion ratio (`k`), the equilibrium frequencies
(`pi`) and the DNA or RNA alphabet (`a`).


## Creating a new module

Let's create a new module called `Bio.MyModule` that
contains a function for squaring numbers.  First we create a new
module at `haskell/Bio/MyModule.hs`.  Module names must begin with
an upper-case letter.  After the first letter, lower-case letters,
numbers, and `_` are allowed. 

Then we add the following to the file:
```Haskell
module Bio.MyModule where

square x = x * x
```

After we rerun `ninja install`, the function `square` module will be
accessible to model files that import `Bio.MyModule`.

## Using a function from the command line

To make a Haskell function accessible from the command line, you must
add a JSON file to the directory `bindings/`. For example, to add our
a function `square` in the module `Bio.MyModule` to the command line
interface, we could add a file called `bindings/functions/square.json`
containing the text: 
``` json
{
    "name": "square",
    "result_type": "Double",
    "import": ["Bio.MyModule"],
    "call": "square(x)",
    "args": [
        {
            "arg_name": "x",
            "arg_type": "Double",
        }
    ]
}
```
* The `name` property determines the name that is visible on the command line.
* The `result_type` property specifies the type of object returned by the function.
* The `import` property gives a list of modules that need to be imported to find the function.
* The `call` property specifies which Haskell function to call, and which arguments to pass.
* The `args` array specifies the name and type for each argument.

When you reinstall BAli-Phy, this file will land in the bindings
directory, and you will be able to run `bali-phy help square`.

See additional explanation (forthcoming) for writing help for functions.

See additional explanation on writing default arguments or priors for functions.