How can I express a type in F# that optionally recurses on itself (infinitely) - recursion

As a learning exercise I am trying to implment a parser for the graphviz dot language (The DOT language) using the functional parser library fparsec (FParsec). The language describes graphs.
Looking at the language definition I was compelled to write down the following definition:
let rec pstmt_list = opt(pstmt .>> opt(pchar ';') >>. opt pstmt_list)
Where pstmt and pchar ';' are parsers, .>> and >>. combine an occurence of the left parser with an occurence of the right parser, and opt parsers an optional occurrence of its argument parser as an option value. However this definition does not work complaining "... the resulting type would be infinite ...".
This example is probably most easily understood by taking a look at the DOT language linked above.
I am aware of the following seemingly linked questions:
Are Infinite Types (aka Recursive Types) not possible in F#?
Haskell to F# - declare a recursive types in f#
But my F# knowledge may not be sufficient to translate them yet, if they apply here at all.

FParsec provides special combinators for parsing sequences. Normally you should prefer these combinators to reimplementing them with a recursive function. You can find an overview of the available combinators for parsing sequences here: http://www.quanttec.com/fparsec/reference/parser-overview.html#parsing-sequences
In this example pstmt_list is a sequence of statements separated and optionally ended by semicolons, so you could easily define the parser as
let pstmt_list = sepEndBy pstmt (pstring ";")

The problem is that your pstmt_list parser produces some values of some type, but when you use it in the definition, you wrap the values of this type with additional option type (using the opt combinator).
The F# compiler thinks that the type of the values returned by the parser e.g. 'a should be the same as the wrapped type option 'a (which is, of course, not possible).
Anyway, I don't think that this is quite what you need to do - the .>> combinator creates a parser that returns the result of the second argument, which means that you'll be ignoring all the results of pstmt parsed so far.
I think you probably need something like this:
let rec pstmt_list : Parser<int list, unit> =
parse.Delay(fun () ->
opt(pstmt .>> pchar ';') .>>. opt pstmt_list
|>> (function Some(prev), Some(rest) -> prev::rest
| Some(prev), _ -> [prev]
| _, Some(rest) -> rest
| _ -> [] ))
The additional use of Delay is to avoid declaring a value that refers directly to itself.

Related

SProxy in purescript?

What's the use of Sproxy in purescript?
In Pursuit, it's written as
data SProxy (sym :: Symbol)
--| A value-level proxy for a type-level symbol.
and what is meant by Symbol in purescipt?
First, please note that PureScript now has polykinds since version 0.14 and most functions now use Proxy instead of SProxy. Proxy is basically a generalisation of SProxy.
About Symbols and Strings
PureScript knows value level strings (known as String) and type level strings (known as Symbol).
A String can have any string value at runtime. The compiler does not track the value of the string.
A Symbol is different, it can only have one value (but remember, it is on the type level). The compiler keeps track of this string. This allows the compiler to type check certain expressions.
Symbols in Practice
The most prominent use of Symbols is in records. The difference between a Record and a String-Map is that the compiler knows about the keys at compile time and can typecheck lookups.
Now, sometimes we need to bridge the gap between these two worlds: The type level and the value level world. Maybe you know that PureScript records are implemented as JavaScript objects in the official compiler. This means we need to somehow receive a string value from our symbol. The magical function reflectSymbol allows us to turn a symbol into a string. But a symbol is on the type level. This means we can only write a symbol where we can write types (so for example in type definition after ::). This is where the Proxy hack comes in. The SProxy is a simple value that "stores" the type by applying it.
For example the get function from purescript-records allows us to get a value at a property from a record.
get :: forall proxy r r' l a. IsSymbol l => Cons l a r' r => proxy l -> Record r -> a
If we apply the first paramerter we get:
get (Proxy :: Proxy "x") :: forall r a. { x :: a | r } -> a
Now you could argue that you can get the same function by simply writing:
_.x :: forall r a. { x :: a | r } -> a
It has exactly the same type. This leads to one last question:
But why?
Well, there are certain meta programming szenarios, where you don't programm for a specific symbol, but rather for any symbol. Imagine you want to write a JSON serialiser for any record. You might want to "iterate" over every property of the record, get the value, turn the value itself into JSON and then concatinate the key value pair with all the other keys and values.
An example for such an implementation can be found here
This is maybe not the most technical explanation of it all, but this is how I understand it.

Ocaml - Runtime compilation of code as a string

I want to parse and compile a function that I have written at runtime, for example I have the following string I generated at runtime:
let str = "fun x y z -> [x; y; z;]"
I am looking for something that will allow me to do something similar to:
let myfun = eval str
(* eval returns the value returned by the code in the string so myfun will
have the type: 'a -> 'a -> 'a -> 'a list*)
Is there a way to do that in OCaml? I came across Dynlink but I am looking for a simpler way to do it.
There is no easier solution than compiling the code and Dynlinking the resulting library.
Or equivalently, one can use the REPL, write the string to the file system and them load it with #use.
Depending on your precise use case, MetaOCaml might be an alternative.
Another important point is that types cannot depend on values in a non-dependently typed language. Thus the type of eval needs to be restricted. For instance, in the Dynlinking path, the type of dynamically linked functions will be determined by the type of the hooks used to register them.

How to call two functions and use their results as arguments for each other?

I have code:
let join a ~with':b ~by:key =
let rec a' = link a ~to':b' ~by:key
and b' = link b ~to':a' ~by:(Key.opposite key) in
a'
and compilation result for it is:
Error: This kind of expression is not allowed as right-hand side of
`let rec' build complete
I can rewrite it to:
let join a ~with':b ~by:key =
let rec a'() = link a ~to':(b'()) ~by:key
and b'() = link b ~to':(a'()) ~by:(Key.opposite key) in
a'()
It is compilable variant, but implemented function is infinitely recursive and it is not what I need.
My questions: Why is first implementation invalid? How to call two functions and use their results as arguments for each other?
My compiler version = 4.01.0
The answer to your first question is given in Section 7.3 of the OCaml manual. Here's what it says:
Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.
Your names appear as function arguments, which isn't supported.
I suspect the reason is that you can't assign a semantics otherwise. It seems to me the infinite computation that you see is impossible to avoid in general.

SML '97: what is exactly the standard syntax?

I came to this question, when I wanted to check something about the syntax of functor declarations. I came to two contradictory syntax definitions, while the syntax of Standard ML '97, as its name suggest, is supposed to be part of a standard, defined in “The definition of Standard ML — Revised”.
From the book
“The definition of Standard ML — Revised”, by R. Milner, page 14, on Google Books says:
fundec ::= functor funbinf
funbind ::= funid (strid : sigexp) = strexp <and funbind>
I read it as “A functor gets exactly one argument and cannot be said to match a signature”.
From another reliable source
“Standard ML syntax summary”, by L. Paulson, page 2, on PDF says (schema approximately re‑expressed using the same notation as in the definition of SML '97):
FunctorDeclaration ::= functor FunctorBinding <and FunctorBinding>
FunctorBinding ::= Ident ( FunctorArguments ) : Signature = Structure
FunctorArguments ::= Ident : Signature | Specification
I read it as “A functor may get multiple arguments and may be said to match a signature”.
Question
The two documents says different things, so I'm confused. What is the real definition of Standard ML '97? Or am I just miss‑reading the standard definition?
Chapters 2 and 3 of the Definition only give the bare syntax of the language. That's extended by the "derived forms" (i.e., syntactic sugar) defined in Appendix A, which include the funid (spec) form (which is short for funid (X : sig spec end) with X being opened on the RHS).
See here for a complete SML grammar including all derived forms.

Using ANTLR with Left-Recursive Rules

Basically, I've written a parser for a language with just basic arithmetic operators ( +, -, * / ) etc, but for the minus and plus cases, the Abstract Syntax Tree which is generated has parsed them as right associative when they need to be left associative. Having googled for a solution, I found a tutorial that suggests rewriting the rule from:
Expression ::= Expression <operator> Term | Term`
to
Expression ::= Term <operator> Expression*
However, in my head this seems to generate the tree the wrong way round. Any pointers on a way to resolve this issue?
First, I think you meant
Expression ::= Term (<operator> Expression)*
Back to your question: You do not need to "resolve the issue", because ANTLR has no problem dealing with tail recursion. I'm nearly certain that it replaces tail recursion with a loop in the code that it generates. This tutorial (search for the chapter called "Expressions" on the page) explains how to arrive at the e1 = e2 (op e2)* structure. In general, though, you define expressions in terms of higher-priority expressions, so the actual recursive call happens only when you process parentheses and function parameters:
expression : relationalExpression (('and'|'or') relationalExpression)*;
relationalExpression : addingExpression ((EQUALS|NOT_EQUALS|GT|GTE|LT|LTE) addingExpression)*;
addingExpression : multiplyingExpression ((PLUS|MINUS) multiplyingExpression)*;
multiplyingExpression : signExpression ((TIMES|DIV|'mod') signExpression)*;
signExpression : (PLUS|MINUS)* primeExpression;
primeExpression : literal | variable | LPAREN expression /* recursion!!! */ RPAREN;

Resources