I can't seem to find the correct typing for an infinite list in ReScript.
I first tried:
type rec stream<'a> = ('a, () => ('a, stream<'a>))
Which was incorrect because ReScript thought the type was cyclic. So instead I tried:
type rec stream<'a> = ('a, Lazy.t<() => ('a, stream<'a>)>)
Which still gave me a type error.
Ultimately I am trying to get this piece of code to work but it fails due to the type signature being infinite.
let rec from: (int, Lazy.t<() => (int, Lazy.t<...>) = (x: int) => {
(x, () => Lazy.from_fun(from(x+1)))
}
If your only objection to Sequence is the Nil case, you can define
type rec stream<'a> = { x:'a, next:() => stream<'a> }
The difference with your definition is that we are creating a new recursive type, rather than trying to define a recursive type expression.
EDIT:
The difference between using a tuple or a record is that tuples are structurally typed whereas records are nominally typed.
This changes everything in term of equality and identity.
In particular the original definition can be read as
type stream0<'a> = ('a, () => 'b ) as 'b
Then whenever one wants to compare a type stream0<'a> with a tuple type, it might be needed to expand this abbreviation an unbounded number of time.
For instance, this function is well-typed.
let f: stream0<int> => (int, ()=>(int,() => _)) = (x) => x
or this one:
let app_once = ((x,next)) => next ()
One important consequence here is that it is possible to use a stream0<'a> in a context where a finite stream was expected.
In other words, there are many have many potential equality between a stream0<'a> and a finite version of stream0<'a>.
Contrarily, the record definition of stream<'a> create a new and distinct type constructor stream. Consequently, a stream<'a> can only ever be equal to stream<'a>. In other words, a function designed for a stream<'a>
let app_once = {x;next} => next(())
cannot work with the type
type one_stream<'a> = { x:'a, next:() => ('a, ()) }
In practice, the recursive type of stream0<'a> and its many type equalities is more bothersome than useful, and such recursive types are disabled by default.
Related
Some functions in the List module fail when the argument is an empty list. List.rev is an example. The problem is the dreaded Value Restriction.
I met the same problem while trying to define a function that returns a list with all but the last element of a list:
let takeAllButLast (xs: 'a list) =
xs |> List.take (xs.Length - 1)
The function works well with nonempty lists, but a version that would handle empty lists fails:
let takeAllButLast (xs: 'a list) =
if List.isEmpty xs then []
else xs |> List.take (xs.Length - 1)
takeAllButLast []
error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : '_a list, etc.
I tried several things: making it an inline function, not specifying a type for the argument, specifying a type for the returned value, making the function depend on a type argument, and using the Option type to obtain an intermediate result later converted to list<'a>. Nothing worked.
For example, this function has the same problem:
let takeAllButLast<'a> (xs: 'a list) =
let empty : 'a list = []
if List.isEmpty xs then empty
else xs |> List.take (xs.Length - 1)
A similar question was asked before in SO: F# value restriction in empty list but the only answer also fails when the argument is an empty list.
Is there a way to write a function that handles both empty and nonempty lists?
Note: The question is not specific to a function that returns all but the last element of a list.
The function itself is completely fine. The function does not "fail".
You do not need to modify the body of the function. It is correct.
The problem is only with the way you're trying to call the function: takeAllButLast []. Here, the compiler doesn't know what type the result should have. Should it be string list? Or should it be int list? Maybe bool list? No way for the compiler to know. So it complains.
In order to compile such call, you need to help the compiler out: just tell it what type you expect to get. This can be done either from context:
// The compiler gleans the result type from the type of receiving variable `l`
let l: int list = takeAllButLast []
// Here, the compiler gleans the type from what function `f` expects:
let f (l: int list) = printfn "The list: %A" l
f (takeAllButLast [])
Or you can declare the type of the call expression directly:
(takeAllButLast [] : int list)
Or you can declare the type of the function, and then call it:
(takeAllButLast : int list -> int list) []
You can also do this in two steps:
let takeAllButLast_Int : int list -> int list = takeAllButLast
takeAllButLast_Int []
In every case the principle is the same: the compiler needs to know from somewhere what type you expect here.
Alternatively, you can give it a name and make that name generic:
let x<'a> = takeAllButLast [] : 'a list
Such value can be accessed as if it was a regular value, but behind the scenes it is compiled as a parameterless generic function, which means that every access to it will result in execution of its body. This is how List.empty and similar "generic values" are implemented in the standard library.
But of course, if you try to evaluate such value in F# interactive, you'll face the very same gotcha again - the type must be known - and you'll have to work around it anyway:
> x // value restriction
> (x : int list) // works
I am using ocaml_plugin to write calculator which is able to evaluate OCaml expressions at run time.
This is my plugin interface.
open Ocaml_plugin.Std
module type S = sig
val f : unit -> float
end
let univ_constr : (module S) Ocaml_dynloader.Univ_constr.t =
Ocaml_dynloader.Univ_constr.create ()
I am able to load functions with the signature unit -> float, for example,
let f () = 3.14159
let f () = 1.5 *. 1.5 *. 3.
and call f () in the main program to evaluate the expression in the function body. However, it supports float type only.
What should I do if I want it to support int? Time.t? Or any arbitrary OCaml type in Pervasive?
let f () = List.length [1;2;3] (* int *)
let f () = Time.now () (* Time.t *)
let f () = "hello world!!!" (* string *)
In order to evaluate at run time, ocaml_plugin seems to be the only way to go. However, in order to let the loader/compiler know what is loaded dynamically, I have to write an interface. How should I change the interface file so that it supports other types?
GADT (Generalized Algebraic Data Type) to rescue.
Although GADT exists for a long time, it is a relatively new topic in OCaml. It helps a lot in writing generic libraries in OCaml safely.
module Value = struct
type 'a t
module Packed = struct
type 'a unpacked = 'a t
type t = T : 'a unpacked -> t
end
end
Value.Packed.t is a packed data type that we want. Theotically any data type 'a can be packed.
I'm solving an old exam to practice SML. One task I found interesting was: Write a function repeat that executes another function with the signature 'a -> 'a.
I assumed the requested function is a curry function and used the o-Operator:
fun repeat (1, f: 'a->'a) = f
| repeat (n, f: 'a->'a) = f o repeat (n-1, f);
However, the o operator was not formally introduced in out course, and I wonder how I could write this without it?
Not the less verbose, but in some way, the most explicit, then after, the less verbose, with explanations.
A curried function is a function getting a single argument. If an expression has more arguments, then there are as many nested functions. The first outer level function gets an argument, and is made of an inner level function which may it‑self be made of an inner function, and so on. Any of this inner level function may be returned, not just the innermost, as explained later (this is a kind of “partial evaluation”). An inner function is “specialized” with the arguments (formally, the arguments are bound in a closure) of the outer functions.
We know there are at least a function argument f and integer argument counter. There needs to be an argument seed also, to invoke the function f the first time.
The order of nesting may be arbitrary or specified. If not specified, I personally prefer to put the least varying arguments on the outer‑scope and the most varying in the inner‑scope. Here, I would say it is, from least to most varying: f, counter seed.
This is already enough to suggest the beginning of a template:
val repeat: ('a -> 'a) -> int -> 'a -> 'a =
fn f: 'a -> 'a =>
fn count: int =>
fn seed: 'a =>
…
We already implemented the ('a -> 'a) -> int -> 'a part of the signature. Remains the last -> 'a which means an 'a is to be returned, and it will be evaluated by an inner loop.
A loop may be something of this form (in pseudo‑code):
val rec loop = fn i =>
if condition-to-stop
then return-something-or-`()`
else loop (i + 1) or (i - 1)
If the loop is to compute something, it will need an extra argument acting as an accumulator, and will return that accumulator as its final result.
Implementing the loop and putting it inside the curried function template above, we get:
val repeat: ('a -> 'a) -> int -> 'a -> 'a =
fn f: 'a -> 'a =>
fn count: int =>
fn seed: 'a =>
let
val rec loop = fn (counter, x) =>
if counter <= 0 then x
else loop (counter - 1, f x)
in
loop (count, seed)
end
Do you understand the let … in … end construct here?
Note the guard on counter may use a pattern as you did, but as SML's integer may be negative (there is no strict natural in SML), that's safer to catch this case too, thus the if … then … else instead of a pattern matching. Mileage may vary on that point, but that's not the question's focus.
The same as above, using fun instead of val rec:
fun repeat (f: 'a -> 'a) (count: int) (seed: 'a): 'a =
let
fun loop (counter, x) =
if counter <= 0 then x
else loop (counter - 1, f x)
in
loop (count, seed)
end
Note for repeat the arguments are not separated by a , (neither a *). This is the way to write a curried function using fun (on the contrary, loop is not curried). Compare it with the prior val version of the same function. If no type is specified and only names, the parenthesis can be omitted.
A test function to be used as the f argument:
val appendAnX = fn s: string => s ^ "x"
The test:
val () = print (repeat appendAnX 5 "Blah:")
Curried function are more abstract than function getting a tuple (which is formally a single argument, thus makes a curried function too, but that's another story and a bit cheating), as the outer function(s) may be partially applied:
This is a partial application, leaving the last argument, seed, unbound:
val repeatAppendAnXThreeTimes = repeat appendAnX 3
Then this function may be applied specifiying only this seed:
val () = print (repeatAppendAnXThreeTimes "Blah:")
Similarly, both counter and seed may be left free:
val repeatAppendAnX = repeat appendAnX
val () = print (repeatAppendAnX 4 "Blah:")
Another way of defining repeatAppendAnXThreeTimes. Compare it to its other definition above:
val repeatAppendAnXThreeTimes = repeatAppendAnX 3
val () = print (repeatAppendAnXThreeTimes "Blah:")
I have an assignment that involves making church numerals in SML. I've looked around and just can't find what I'm doing wrong. The goal is to make a function that takes an int and returns a church numeral, defined as datatype 'a numeral = Num of ('a -> 'a) -> 'a -> 'a (which is predefined by my teacher). Then to make a second function that takes a church numeral and returns an int.
I saw a previous post with the code:
val ZERO = C(fn (f,x) => x)
fun subCreate 0 (f,x) = x
| subCreate n (f,x) = f (subCreate (n-1) (f,x))
fun create n = C(fn (f,x) => subCreate n (f,x));
fun churchToInt (c, cn) = cn ((fn x => x+1), 0) 0;
but this does not work, and gives the error type vars not generalized because of value restriction are instantiated to dummy types.
When I used the code:
val zero = fn s => fn x => x;
(to define a zero) and then
val next = fn n => fn s => fn x => (f ((n s) x));
(just to do a test to see if I could increment zero, before setting up an iterative or recursive function), I got the same error. I've spent hours on this problem, unable to produce a church numeral. Can someone point me in the right direction?
I think you are running into the "value polymorphism" in SML'97. Here is a very long section of documentation discussing it.
One workaround is, whenever you have an expression which causes this problem, e.g. next zero, wrap a function around it, e.g. fn x => next zero x.
Another thing I think you could do is instead of evaluating definitions at the top level in the interpreter, wrap the definition and all the code that uses it into local scope (e.g. inside let ... in ... end) or into functions.
I have to create a function about peano numbers defined as the following datatype:
datatype 'a peano = P of ('a -> 'a) * 'a -> 'a
val zero = P(fn (f, x) => x)
The function that I have to implement finds the succesive peano number of the peano parameter P(p). This is what I have written:
fun suc (P(p)) = case P(p) of P(fn(f,x)=>x) => P(fn(f,x)=>f(x));
The problem is that i get these errors:
stdIn:4.33-4.36 Error: syntax error: deleting FN LPAREN
stdIn:4.43 Error: syntax error found at RPAREN
I don't know what Im doing wrong. Please help!
There are a number of problems in this code. The one the compiler is whining about is that you have a function definition
fn (f,x) => x
on the left-hand side of a case arm, where only patterns are permitted.
Some other problems:
Redundant parentheses make the code hard to read (advice is available on removing them).
Your case expression is redundant; in the function definition
fun suc (P p) = ...
it should be possible just to compute with p without any more case analysis.
Since P carries a function, you will probably have an easier time if you write
fun suc (P f) = ...
and make sure that in the result, f is applied to a pair (as required by the datatype declarations).