F# - Create a Recursive Discriminated Union at Runtime - recursion

I am trying to write a simple interpreter to control a Turtle using F#.
I have created the following recursive union type to represent the few commands that the Turtle will accept. The code will be represented by a "Command list" that shouldn't be too hard to execute with a simple recursive function.
type Command =
| Repeat of amount * Command list
| Forward of amount
| Turn of direction * amount
I want to make this interpreter white space delineated so the source could look as follows.
Forward 75
Repeat 4
Forward 10
Turn Right 50
Repeat 6
Forward 20
Turn Right 60
Repeat 8
Forward 15
Turn Left 30
Turn Right 10
Forward 25
I then have this function to separate everything into an int*string list based on the indentation level. So Repeat 4 would become (0, "Repeat 4"), Forward 10 would be (1, "Forward 10"), and Turn Left 30 would be (3, "Turn Left 30").
/// Creates indentation chart for generating a syntax tree by cycling
/// through a list of strings generated
/// by string.Split and counting the empty strings before each non-empty
//// string.
let indent strs =
let rec inner strs search cmds indent temp =
match strs, search with
| [], _ -> (indent,temp)::cmds
| ""::tail, Cmd -> inner tail Indent ((indent,temp)::cmds) 0 "" //
Newline started -> push cached counter and command string
| ""::tail, Indent -> inner tail Indent cmds (indent+1) temp // Next
level of indent -> increment indent counter
| h::tail, Cmd -> inner tail Cmd cmds indent (temp + " " + h)
| h::tail, Indent -> inner tail Cmd cmds indent (temp + h)
| h::tail, Start -> inner tail Cmd cmds indent (temp + h)
inner strs Start [] 0 "" |> List.rev
let splitIndent (text:string) = text.Trim().Split() |> Array.toList |>
indent
Now this is where I am stuck. I have the list of commands with their indentation levels, but I do not know how to dynamically create a recursive discriminated union. I know how to hardcode it in. It looks something like this,
let tree = [
Forward 75
Repeat (4, [
Forward 10
Turn (Right, 50)
Repeat (6, [
Forward 20
Turn (Right, 60)
Repeat (8, [
Forward 15
Turn (Left, 30)
])])
Turn (Right, 10)])
Forward 25]
but I do not know how to generate something like this based on different input strings.
I have read many StackOverflow posts related to trees, discriminated unions, and creating recursive types like this dynamically but I have not found anything that fits my needs. I have tried modifying the few examples that I have found and the closest I found was an answer by Tomas Petricek at F# transform list to a tree. Plugging in the union cases and the pattern matching for them to get this to work got me a lot closer, but it left off a lot of commands and duplicated some of the others.
This is the best that I have come up with so far, but it does not get all of the commands.
/// Takes the indent,command pairs list and produces a list of commands.
/// Some of these are nested in a tree structure based on their indent.
let buildProgram (diagram:(int*string) list) : Command list =
let rec collect indx lis commands =
match lis with
| [] -> commands
| x::xs ->
match fst x with
| i when i = indx ->
match split (snd x) with
| "Forward"::NUM n::tail -> collect i xs commands#[Forward
n]
| "Turn"::ARG a::NUM n::tail -> collect i xs
commands#[Turn(a,n)]
| "Repeat"::NUM n::tail -> commands#([(Repeat (n, (collect
(i+1) xs [])))] |> List.rev)
| i when i < indx ->
match split (snd x) with
| "Forward"::NUM n::tail -> collect (i-1) xs
commands#[Forward n]
| "Turn"::ARG a::NUM n::tail -> collect (i-1) xs
commands#[Turn(a,n)]
| "Repeat"::NUM n::tail -> commands#([(Repeat (n, (collect
(i-1) xs [])))] |> List.rev)
collect 0 diagram [] |> List.rev
How do you create a recursive discriminated union at runtime based on different inputs?

What you're trying to do there is to write a parser for your indentation-based syntax that would produce values of type Command.
You can certainly roll one by hand, but the general advice would be to use a parser combinator library such as FParsec. FParsec does have a steep learning curve, but it's "the way to go" for writing parsers in F#.
You will find this article particularly helpful if you decide to go with that - Parsing indentation based syntax with FParsec.

Related

Map List onto shifted self

I have finally found an excellent entry point into functional programming with elm, and boy, do I like it, yet I still lack some probably fundamental elegance concerning a few concepts.
I often find myself writing code similar to the one below, which seems to be doing what it should, but if someone more experienced could suggest a more compact and direct approach, I am sure that could give some valuable insights into this so(u)rcery.
What I imagine this could boil down to, is something like the following
(<-> is a vector subtraction operator):
edgeDirections : List Vector -> List Vector
edgeDirections corners = List.map2 (\p v -> p <-> v) corners (shiftr 1 corners)
but I don't really have a satisfying approach to a method that would do a shiftr.
But the rules of stackoverflow demand it, here is what I tried. I wrote an ugly example of a possible usage for shiftr (I absolutely dislike the Debug.crash and I am not happy about the Maybe):
Given a list of vectors (the corner points of a polygon), calculate the directional vectors by calculating the difference of each corner-vector to its previous one, starting with the diff between the first and the last entry in the list.
[v1,v2,v3] -> [v1-v3,v2-v1,v3-v2]
Here goes:
edgeDir : Vector -> ( Maybe Vector, List Vector ) -> ( Maybe Vector, List Vector )
edgeDir p ( v, list ) =
case v of
Nothing ->
Debug.crash ("nono")
Just vector ->
( Just p, list ++ [ p <-> vector ] )
edgeDirections : List Vector -> List Vector
edgeDirections corners =
let
last =
List.head <| List.reverse corners
in
snd <| List.foldl edgeDir ( last, [] ) corners
main =
show <| edgeDirections [ Vector -1 0, Vector 0 1, Vector 1 0 ]
I appreciate any insight into how this result could be achieved in a more direct manner, maybe using existing language constructs I am not aware of yet, or any pointers on how to lessen the pain with Maybe. The latter may Just not be possible, but I am certain that the former will a) blow me away and b) make me scratch my head a couple times :)
Thank you, and many thanks for this felicitous language!
If Elm had built-in init and last functions, this could be cleaner.
You can get away from all those Maybes by doing some pattern matching. Here's my attempt using just pattern matching and an accumulator.
import List exposing (map2, append, reverse)
shiftr list =
let shiftr' acc rest =
case rest of
[] -> []
[x] -> x :: reverse acc
(x::xs) -> shiftr' (x::acc) xs
in shiftr' [] list
edgeDirections vectors =
map2 (<->) vectors <| shiftr vectors
Notice also the shortened writing of the mapping function of (<->), which is equivalent to (\p v -> p <-> v).
Suppose Elm did have an init and last function - let's just define those quickly here:
init list =
case list of
[] -> Nothing
[_] -> Just []
(x::xs) -> Maybe.map ((::) x) <| init xs
last list =
case list of
[] -> Nothing
[x] -> Just x
(_::xs) -> last xs
Then your shiftr function could be shortened to something like:
shiftr list =
case (init list, last list) of
(Just i, Just l) -> l :: i
_ -> list
Just after I "hung up", I came up with this, but I am sure this can still be greatly improved upon, if it's even correct (and it only works for n=1)
shiftr : List a -> List a
shiftr list =
let
rev =
List.reverse list
in
case List.head rev of
Nothing ->
list
Just t ->
[ t ] ++ (List.reverse <| List.drop 1 rev)
main =
show (shiftr [ 1, 2, 3, 4 ] |> shiftr)

Regarding OCaml Pattern Matching Syntax

I am following this OCaml tutorial.
They provided the two functions below and said that they are equivalent.
let string_of_int x = match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
let string_of_int2 = function
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| _ -> "many"
My query is regarding the syntax of the above functions.
I wrote the same function but instead of | 0 -> I simply did 0 -> and the function still works in the same way. Is there any particular reason that the tutorial added the extra | in their function?
In the second function what is the use of the function keyword and why was this keyword absent in the first function?
Some people think it looks nicer and more organized, and it allows you to change the order of cases using cut & paste without having to worry about which one didn't have the |.
The function syntax is an abbreviation: function [CASES] is the same as fun x -> match x with [CASES]. There is a subtle difference, which is with function it is not possible to shadow another variable by the name of the parameter.
let string_of_int x = [EXP] is itself an abbreviation for let string_of_int = fun x -> [EXP].
So, to a close approximation, the "canonical" syntax uses fun and match, everything else is sugar. If you apply these two expansions to the two versions of the function, you will see that the same code results (modulo alpha-equivalence, of course :) ).

Default recursion on recursive types

Idiomatic F# can nicely represent the classic recursive expression data structure:
type Expression =
| Number of int
| Add of Expression * Expression
| Multiply of Expression * Expression
| Variable of string
together with recursive functions thereon:
let rec simplify_add (exp: Expression): Expression =
match exp with
| Add (x, Number 0) -> x
| Add (Number 0, x) -> x
| _ -> exp
... oops, that doesn't work as written; simplify_add needs to recur into subexpressions. In this toy example that's easy enough to do, only a couple of extra lines of code, but in a real program there would be dozens of expression types; one would prefer to avoid adding dozens of lines of boilerplate to every function that operates on expressions.
Is there any way to express 'by default, recur on subexpressions'? Something like:
let rec simplify_add (exp: Expression): Expression =
match exp with
| Add (x, Number 0) -> x
| Add (Number 0, x) -> x
| _ -> recur simplify_add exp
where recur might perhaps be some sort of higher-order function that uses reflection to look up the type definition or somesuch?
Unfortunately, F# does not give you any recursive function for processing your data type "for free". You could probably generate one using reflection - this would be valid if you have a lot of recursive types, but it might not be worth it in normal situations.
There are various patterns that you can use to hide the repetition though. One that I find particularly nice is based on the ExprShape module from standard F# libraries. The idea is to define an active pattern that gives you a view of your type as either leaf (with no nested sub-expressions) or node (with a list of sub-expressions):
type ShapeInfo = Shape of Expression
// View expression as a node or leaf. The 'Shape' just stores
// the original expression to keep its original structure
let (|Leaf|Node|) e =
match e with
| Number n -> Leaf(Shape e)
| Add(e1, e2) -> Node(Shape e, [e1; e2])
| Multiply(e1, e2) -> Node(Shape e, [e1; e2])
| Variable s -> Leaf(Shape e)
// Reconstruct an expression from shape, using new list
// of sub-expressions in the node case.
let FromLeaf(Shape e) = e
let FromNode(Shape e, args) =
match e, args with
| Add(_, _), [e1; e2] -> Add(e1, e2)
| Multiply(_, _), [e1; e2] -> Multiply(e1, e2)
| _ -> failwith "Wrong format"
This is some boilerplate code that you'd have to write. But the nice thing is that we can now write the recursive simplifyAdd function using just your special cases and two additional patterns for leaf and node:
let rec simplifyAdd exp =
match exp with
// Special cases for this particular function
| Add (x, Number 0) -> x
| Add (Number 0, x) -> x
// This now captures all other recursive/leaf cases
| Node (n, exps) -> FromNode(n, List.map simplifyAdd exps)
| Leaf _ -> exp

Erlang- Recursive Delete

I am working on writing a recursive function in erlang that given an element X and a list, deletes the element X from the list and returns the new list. I believe I have written it correctly, however, when I run a test on it, I am thrown into an infinite loop..
delete(_,[]) -> [];
delete(X,[X|_]) -> [];
delete(X,[Y|YS]) ->
if X == Y -> YS;
true -> [Y] ++ delete(X,[YS]) % I believe the infinite loop is a result of this line..
end.
I am very new to erlang (this is my second project using the language), so troubleshooting is a bit difficult for me, but if anyone could provide some guidance, it would be much appreciated. Thank you in advance!
delete(_,[]) -> []; %% ok removing anything from an empty list gives an empty list
delete(X,[X|_]) -> []; %% big mistake. If you find the element you want to remove on top
%% of the list, you must remove it and continue with the rest of the list
delete(X,[Y|YS]) ->
if X == Y -> YS; %% this will never occurs since you already test this case
%% in the previous clause. An the result should be delete(X,YS), not YS.
true -> [Y] ++ delete(X,[YS]) %% correct
end.
I don't see where you have an infinite loop, but the second clause will make the recursive calls stop too early.
So your code should be:
delete(_,[]) -> [];
delete(X,[X|Rest]) -> delete(X,Rest);
delete(X,[Y|YS]) -> [Y] ++ delete(X,[YS]).
but a I would recommend to use list comprehension for a very short code and fast execution (it is the code used in lists:filter/2):
delete(X,L) -> [Y || Y <- L, Y =/= X].
% ^ ^ ^
% | | |_ when Y different from X
% | |_________ with all the elements Y from L
% |__________________ make a list
defining the function in the shell, you get:
1> D = fun D(_,[]) -> [];
1> D(X,[X|R]) -> D(X,R);
1> D(X,[Y|R]) -> [Y] ++ D(X,R) end.
#Fun<erl_eval.36.90072148>
2> D(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
3> D1 = fun(X,L) -> [Y || Y <- L, Y =/= X] end.
#Fun<erl_eval.12.90072148>
4> D1(4,[1,2,3,4,5,6]).
[1,2,3,5,6]
5>
First off, I don't know why you would need the second clause. Basically it's saying "If the first item in the list matches the item to be removed, through the whole list away and return an empty one".
The easiest way to do this is to start with the list and an empty list to store the result. Then as we iterate over the items in the list, we add items that don't match to the result and ignore items that match the item we want deleted. This will remove all occurrences of X in List:
delete(X, List) -> delete(X, List, []). % Provide the same API as before
delete(_,[], Result) -> Result; % If the list is empty we are done.
delete(X,[Y|YS], Result) ->
case X == Y of
true ->
delete(X,[YS], Result);
false ->
delete(X,[Y|YS], Result)
end.
But why not use lists:filter/2? It makes it much simpler:
delete(X, List) ->
lists:filter(fun(Item) ->
Item /= X
end, List).

F# replacing variables with actual values results in endless loop (recursive function)

I recently started with F# and implemented a very basic recursive function that represents the Sieve of Eratosthenes. I came up with the following, working code:
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail -> let rest = tail |> List.filter(fun number -> number % head <> 0L)
let newAccumulator = head::accumulator
Prime.SieveOfEratosthenesRecursive rest newAccumulator
This function is not really memory efficient so I tried to eliminate the variables "rest" and "newAccumulator". I came up with the following code
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail -> tail |> List.filter(fun number -> number % head <> 0L)
|> Prime.SieveOfEratosthenesRecursive (head::accumulator)
As far as I understand the tutorials I've read Prime.SieveOfEratosthenesRecursive will be called with the filtered tail as first parameter and a list consisting of head::accumulator as second one. However when I try to run the code with the reduced variable usage, the program gets trappen in an infinite loop. Why is this happening and what did I do wrong?
As far as I understand the tutorials I've read Prime.SieveOfEratosthenesRecursive will be called with the filtered tail as first parameter and a list consisting of head::accumulator as second one.
You have this backwards.
In the first version, you're passing rest then newAccumulator; in the second version, you're effectively passing newAccumulator then rest. I.e., you've transposed the arguments.
Prime.SieveOfEratosthenesRecursive (head::accumulator) is a partial function application wherein you're applying (head::accumulator) as the first argument (sequence). This partial function application yields a unary function (expecting accumulator), to which you are passing (via |>) what is called rest in the first version of your code.
Changing SieveOfEratosthenesRecursive's argument order is the easiest solution, but I would consider something like the following idiomatic as well:
static member internal SieveOfEratosthenesRecursive sequence accumulator =
match sequence with
| [] -> accumulator
| head::tail ->
tail
|> List.filter(fun number -> number % head <> 0L)
|> Prime.SieveOfEratosthenesRecursive <| (head::accumulator)
or
static member internal SieveOfEratosthenesRecursive sequence accumulator =
let inline flipzip a b = b, a
match sequence with
| [] -> accumulator
| head::tail ->
tail
|> List.filter(fun number -> number % head <> 0L)
|> flipzip (head::accumulator)
||> Prime.SieveOfEratosthenesRecursive
FWIW, eliminating rest and newAccumulator as named variables here is not going to impact your memory usage in the slightest.
The last call in your second function is equivalent to:
Prime.SieveOfEratosthenesRecursive newAccumulator rest
where you switch positions of two params. Since newAccumulator grows bigger after each recursive call, you will never reach the base case of empty list.
The rule of thumb is putting the most frequently changing parameter at last:
let rec sieve acc xs =
match xs with
| [] -> acc
| x::xs' -> xs' |> List.filter (fun y -> y % x <> 0L)
|> sieve (x::acc)
The above function could be shortened using function keyword:
let rec sieve acc = function
| [] -> acc
| x::xs' -> xs' |> List.filter (fun y -> y % x <> 0L)
|> sieve (x::acc)
Using pipe (|>) operator only makes the function more readable, it doesn't affect memory usage at all.

Resources