### XPath expressions

Write a function that implements //t without using references types and xtransform

1. Give a non tail-recursive version
2. Give a tail-recursive version

## Patterns

### Sort (by Artur Miguel Diaz: http://ctp.di.fct.unl.pt/~amd)

Write a non recursive function of type Int -> Latin1 which given a non-negative number produces all its digits in the order.

The function is given below nearly completely programmed. Define the patterns that allows to produce the result.

```
let sortAlg (n :Int):Latin1 =
match string_of n with
PATTERN -> RESULT
;;
```

Example:

```
fact 200 =
788657867364790503552363213932185062295135977687173263294742533
244359449963403342920304284011984623904177212138919638830257642
790242637105061926624952829931113462857270763317237396988943922
445621451664240254033291864131227428294853277524242407573903240
321257405579568660226031904170324062351700858796178922222789623
703897374720000000000000000000000000000000000000000000000000

sortAlg (fact 200) =
"00000000000000000000000000000000000000000000000000000000000000
000000000000001111111111111111111111111122222222222222222222222
222222222222222222222222222222233333333333333333333333333333333
333333333444444444444444444444444444444444445555555555555555555
555555666666666666666666666666666667777777777777777777777777777
7777777888888888888888888888889999999999999999999999999999999"
```

## Solutions

```type t =   specify here a type to test

fun ( x :[Any*]):[t*] =
let f( x :[Any*]):[t*]) = ...
```

Note here that the recursive function f is wrapped by a second anonymous function so that it does not expose the recursion variable.

```fun (e : [Any*]):[ T*] =
let f( accu :[T*] , x :[Any*]):[T*] =
match x with
[ h&T&<_ ..>(k&[Any*]) ;t] ->  f( accu@[h], k@t)
| [ <_ ..>(k&[Any*]) ;t] ->  f( accu, k@t)
| [ h&T ;t] ->  f( accu@[h], t)
| [ _ ;t] ->  f( accu, t)
| [] -> accu
in f ([], e);;
```

Note that this implementation may generate empty branch warnings in particular

• for the first branch if T&<_ ..>(k&[Any*]) is Empty
• for the second branch if <_ ..>(k&[Any*]) is smaller than T&<_>(k&[Any*])
• for the first branch if t is smaller than <_ ..>(k&[Any*])

### Patterns

```
let sortAlg (n :Int):Latin1 =
match string_of n with
[ (s0::'0' | s1::'1' | s2::'2' | s3::'3' | s4::'4' |
s5::'5' | s6::'6' | s7::'7' | s8::'8' | s9::'9')+ ] ->
s0 @ s1 @ s2 @ s3 @ s4 @ s5 @ s6 @ s7 @ s8 @ s9
| _ -> raise "Invalid argument for sortAlg."
;;
```

You can cut and paste the code on this page and test it on the online interpreter.