Standard ml function in datatype problem - sml

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).

Related

Why does OCaml compiler give this error message regarding type inference?

I have written this helper function in OCaml and it keeps throwing this error.
code:
let rec helper1 f lines d =
match lines with
| [] -> None
| h::t when ( helper2 f h 0) <> -1 -> Some (d, (helper2 f h 0))
| _::t -> helper1 f t d+1;;
error:
|_::t -> helper1 f t d+1;;
^^^^^^^^^^^^^
Error: This expression has type ('a * int) option
but an expression was expected of type int
I need to have the type as ('a *int) option and according to me it looks okay. I am new to OCaml and any help would be appreciated!
It a common problem when learning OCaml. You are assuming that,
f x+1
is interpreter as
f (x+1)
while in fact it means,
(f x) + 1
More formally, in OCaml the function application operator, which is denoted just as a juxtaposition of the function name and its arguments, has higher precedence (binds tighter, evaluated before) than infix operators (e.g., +, -, *, etc).
Now the error message has a clear explanation since you have
helper1 f t d + 1
the compiler sees that you add something (helper1 f t d) to 1 and infers that this something should have type int. On the other hand, from the other occurrences of helper1 it also infers that it has type ('a * int) option, which is clearly not an int. So it indicates an error.

In OCaml, write a function that works Base.Map and Base.Hashtbl

So I want to write a function that takes a first class module as an argument that works on Base.Map and Base.Hashtbl, but I'm running into a problem. This code illustrates what's going on:
module type Len_intf = sig
type t
val length : t -> int
end
let show (type a) (module L : Len_intf with type t = a) h =
printf "len: %d\n" ## L.length h
let test (type a) h =
show (module Hashtbl : Len_intf with type t = a) h
Attempting to compile this results in:
Error: Signature mismatch:
...
Type declarations do not match:
type ('a, 'b) t = ('a, 'b) Poly.t
is not included in
type t
They have different arities.
File "test.ml", line 2, characters 2-8:
Expected declaration
File "src/hashtbl_intf.ml", line 552, characters 2-17:
Actual declaration
Is this even possible, due to the different type arity of Hashtbl and Map?
Writing a function that takes a first-class module is certainly possible (you did so), and it can be called like that:
let test (type a) (type b) h =
let module M = struct
type t = (a,b) Hashtbl.t
let length = Hashtbl.length
end in
show (module M) h
But I do not think it is possible to do it the way you want. Indeed, type equalities come afterwards, in addition to what the signature already describes. They cannot prevent a type arity mismatch.

SML Error: operator and operand don't agree [tycon mismatch]

I'm new to SML and don't quite understand my issue, although I'm certain I'm at fault. First off, here are two short functions I am testing and their descriptions.
MakeInterval - Takes a natural number r, (also used for rp) and a natural number t, and returns the interval [t-r,t+r].
fun MakeInterval(r,rp,t) =
if r + rp < 0 then []
else t-r :: MakeInterval(r-1,rp,t);
E.g. MakeInterval(3,3,10) will return [7,8,9,10,11,12,13]. If you have a suggestion for getting rid of rp, please let me know. It's the only way I could think of to keep track of the original value of r while maintaining sorted order.
NotDivisible - Takes a natural number r, a list of natural numbers ts1 and another list of natural numbers ts2. Code using ts2 isn't yet written.
r specifies the lower and upper bounds of the interval, (same as MakeInterval), and ts1 is a list of numbers to be fed into map with the MakeInterval function.
fun NotDivisible(r, ts1, ts2) =
map (fn x => MakeInterval(r,r,x), ts1);
This function should return a list of intervals. E.g. NotDivisible(3, [10,20,30],
[2,4,6]) will return (for now) [[7..13], [17..23], [27..33]].
After I get this working, I will begin manipulating these lists to find which numbers out of these intervals are indivisible by any of the numbers in ts2.
But for now, my issue lies with the function definitions as I have them. MakeInterval is defined with no issues and I have tested it on it's own. This is the error I receive when attempting to define NotDivisible:
stdIn:5.33-5.71 Error: operator and operand don't agree [tycon mismatch]
operator domain: 'Z -> 'Y
operand: (int -> int list) * 'X
in expression:
map ((fn x => MakeInterval <exp>),ts1)
I've tried specifying all types manually to no avail. Everything makes sense to me logically, but clearly there is a syntax issue here that I am not following.
The issue with the above is the invocation of map, the function is curried
map : ('a -> 'b) -> 'a list -> 'b list;
so, a small change to the parentheses:
fun NotDivisible(r, ts1, ts2) = map (fn x => MakeInterval(r,r,x)) ts1;
gives you:
val NotDivisible = fn : int * int list * 'a -> int list list

How to declare a hasEq constraint?

I'm just starting out with F*, by which I mean I've written a few lines along with the tutorial. So far it's really interesting and I'd like to keep learning.
The first thing I tried to do on my own was to write a type that represents a non-empty list. This was my attempt:
type nonEmptyList 'a = l : (list 'a) { l <> [] }
But I get the error
Failed to verify implicit argument: Subtyping check failed; expected
type (a#6468:Type{(hasEq a#0)}); got type Type
I know I'm on the right track though because, if I constrain my list type to containing strings, this does work:
type nonEmptyList = l : (list string) { l <> [] }
I'm assuming this means that l <> [] in the original example isn't valid because I haven't specified that 'a should support equality. The problem is that I cannot for the life of me figure out how to do that. I guess is has something to do with a higher kind called hasEq, but trying things such as:
type nonEmptyList 'a = l : (list 'a) { hasEq 'a /\ l <> [] }
hasn't gotten me anywhere. The tutorial doesn't cover hasEq and I can't find anything helpful in the examples in the GitHub repo so now I'm stuck.
You correctly identified the problem here. The type 'a that you used in the definition of nonEmptyList is left unspecified and therefore could not support equality. Your intuition is correct, you need to tell F* that 'a is a type that has equality, by adding a refinement on it:
To do that, you can write the following:
type nonEmptyList (a:Type{hasEq a}) = l : (list a) { l <> [] }
Note that the binder I used for the type is a and not 'a. It would cause a syntax error, it makes more sense because it isn't "any" type anymore.
Also, note that you can be even more precise and specify the universe of the type a as Type0 if needbe.
Your analysis is indeed correct, and the accepted answer gives the right solution in general.
For your concrete example, though, you don't need decidable equality on list elements: you can just use (list 'a){ ~ (List.isEmpty l) }.
For reference, here's the definition of isEmpty:
(** [isEmpty l] returns [true] if and only if [l] is empty *)
val isEmpty: list 'a -> Tot bool
let isEmpty l = match l with
| [] -> true
| _ -> false

Alonzo Church numerals in SML

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.