SML recursive type error when converting numbers to nat form - sml

I am practicing SML and getting the following recursive type error. Is ML complaining about type recursive and needs some type hints? I am confused.
datatype 'a nat =
Zero
| Succ of 'a
;
fun to_nat(v) = if v = 0 then Zero else Succ(to_nat(v - 1));
fun plus(n1,n2) =
case n1 of
Zero => n2
| Succ(v) => Succ(plus(v, n2))
;
fun multiply(n1,n2) =
case n1 of
Zero => Zero
| Succ(v) => plus(multiply(v, n2), n2)
;
val five = to_nat(5);
val six = to_nat(6);
val eleven = plus(five, six);
val thirty = multiply(five, six);
Error:
Standard ML of New Jersey v110.79 [built: Sat Oct 26 12:27:04 2019]
[opening lambda.sml]
datatype 'a num = Succ of 'a | Zero
lambda.sml:6.5-6.60 Error: right-hand-side of clause doesn't agree with function result type [circularity]
expression: 'Z num
result type: 'Z
in declaration:
to_num = (fn v => if <exp> = <exp> then Zero else Succ <exp>)
/usr/lib/smlnj/bin/sml: Fatal error -- Uncaught exception Error with 0
raised at ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27

I believe you made a mistake in defining your data type. You want Succ to take a value of type 'a nat rather than 'a.
datatype 'a nat = Zero | Succ of 'a nat;

The 'a parameter makes no sense, and is probably what lead you down the wrong path.
(For instance, Succ "hello" or Succ ([1], true, "world") seem very odd constructs of natural numbers.)
You want just
datatype nat =
Zero
| Succ of nat

Related

Why Peano numbers in OCaml not working due to scope error?

I have the following peano number written with GADTs:
type z = Z of z
type 'a s = Z | S of 'a
type _ t = Z : z t | S : 'n t -> 'n s t
module T = struct
type nonrec 'a t = 'a t
end
type 'a nat = 'a t
type e = T : 'n nat -> e
The following function to decode a 'a nat (or 'a t) into the number it encoded, works:
let to_int : type n. n t -> int =
let rec go : type n. int -> n t -> int =
fun acc n -> match n with Z -> acc | S n -> go (acc + 1) n
in
fun x -> go 0 x
but if I try to rewrite it almost exactly the same this way:
let to_int2 (type a) (a: a nat) : int =
let rec go (type a) (acc : int) (x : a nat) : int =
match x with
| Z -> acc
| S v -> go (acc + 1) v
in
go 0 a
I get a scope error. What's the difference between the two functions?
138 | | S v -> go (acc + 1) v
^
Error: This expression has type $0 t but an expression was expected of type
'a
The type constructor $0 would escape its scope
The root issue is polymorphic recursion, GADTs are a red herring here.
Without an explicit annotation, recursive functions are not polymorphic in their own definition.
For instance, the following function has type int -> int
let rec id x =
let _discard = lazy (id 0) in
x;;
because id is not polymorphic in
let _discard = lazy (id 0) in
and thus id 0 implies that the type of id is int -> 'a which leads to id having type int -> int.
In order to define polymorphic recursive function, one need to add an explicit universally quantified annotation
let rec id : 'a. 'a -> 'a = fun x ->
let _discard = lazy (id 0) in
x
With this change, id recovers its expected 'a -> 'a type.
This requirement does not change with GADTs. Simplifying your code
let rec to_int (type a) (x : a nat) : int =
match x with
| Z -> 0
| S v -> 1 + to_int v
the annotation x: a nat implies that the function to_int only works with a nat, but you are applying to an incompatible type (and ones that lives in a too narrow scope but that is secondary).
Like in the non-GADT case, the solution is to add an explicit polymorphic annotation:
let rec to_int: 'a. 'a nat -> int = fun (type a) (x : a nat) ->
match x with
| Z -> 0
| S v -> 1 + to_int v
Since the form 'a. 'a nat -> int = fun (type a) (x : a nat) -> is both a mouthful and quite often needed with recursive function on GADTs, there is a shortcut notation available:
let rec to_int: type a. a nat -> int = fun x ->
match x with
| Z -> 0
| S v -> 1 + to_int v
For people not very familiar with GADTs, this form is the one to prefer whenever one write a GADT function. Indeed, not only this avoids the issue with polymorphic recursion, writing down the explicit type of a function before trying to implement it is generally a good idea with GADTs.
See also https://ocaml.org/manual/polymorphism.html#s:polymorphic-recursion , https://ocaml.org/manual/gadts-tutorial.html#s%3Agadts-recfun , and https://v2.ocaml.org/manual/locallyabstract.html#p:polymorpic-locally-abstract .

operator and operand do not agree [tycon mismatch]

I am trying to write a function in sml that takes in a list of pairs and returns pair of two list of all the elements
Meaning if the input is [(1, 2.0), (2, 3.0)]
The output should be ([1, 2], (2.0, 3.0))
fun divide nil = (nil , nil)
| divide [(a, b)::nil] = ([a], [b])
| divide [(a, b)::myTl] =
let
val (x, y) = divide myTl
in
(a::x, b::y)
end
;
Never the less the sml interpreter returns the following err
Error: operator and operand do not agree [tycon mismatch]
operator domain: ('Z * 'Y) list list
operand: ('Z * 'Y) list
in expression:
divide myTl
The error message you're seeing is because you've (inadvertently) declared a function with domain ('a * 'b) list list due to your input patterns, so your recursive call is not well typed.
The most straightforward fix is to correct for the incorrect use of [ ] around the argument to the function---this is making a singleton list, instead of just grouping the pattern. Thus you'd want to use ( ) instead.
fun divide nil = (nil , nil)
| divide ((a, b)::nil) = ([a], [b])
| divide ((a, b)::myTl) =
let
val (x, y) = divide myTl
in
(a::x, b::y)
end
Your second base case is also extraneous, so we could further revise this to
fun divide [] = ([], [])
| divide ((a, b)::xs) =
let
val (x, y) = divide xs
in
(a::x, b::y)
end

How to return a SOME list instead of a normal list?

I am trying to implement a program that takes a string and a list and returns NONE if it doesn't find any match and the list without the element if it does.
fun all_except_option ("string",["he","she","string"]) = SOME["he","she"]
I have managed to make it working, but without the options type and i have no idea how to make it return SOME list instead a normal list.
fun all_except_option(str,lst)=
case lst of
[] => []
| x::lst' => if same_string(x,str) = false
then let fun append (word, list) = word::list
in append(x,[]) :: all_except_option(str,lst')
end
else all_except_option(str,lst')
Thank you. I managed to make it working, but i still don't understand the "else case" and how is my programm handling it. Here is the working code. I would be glad if you can explain me the "else case all_except_option(str,list') of".
fun all_except_option(str,list)=
case list of
[] => NONE
| x::list' => if same_string(x,str) then
SOME( list')
else case all_except_option(str,list') of
NONE=>NONE
| SOME list'=>SOME(x::list')
implement a program that takes a string and a list and returns NONE if it doesn't find any match and the list without the element if it does.
all_except_option ("string",["he","she","string"]) = SOME ["he","she"]
How is SOME [] different from NONE? As in, if this function returned just a list, it would be possible to say that removing occurrences of "string" results in no other strings: Either the list was empty already, or it contained only occurrences of "string". I am not sure why NONE vs. SOME [] is warranted in one case over the other.
So the better function is one that simply returns a plain list:
fun except (x, ys) = List.filter (fn y => x <> y)
When is it useful to return 'a option?
For example when the return type does not have a way to indicate no result already:
fun lookup k1 [] = NONE
| lookup k1 ((k2,v)::pairs) =
if k1 = k2
then SOME v
else lookup k1 pairs
This function returns 0 or 1 thing. But it's also a simple function because it never aggregates results over its recursion. Recursive functions become complicated when they return composite data types like 'a option when it needs to unpack the result of the recursion.
A good example is an eval function that sometimes fails:
datatype expr
= Add of expr * expr
| Sub of expr * expr
| Mul of expr * expr
| Div of expr * expr
| Int of int
fun eval (Int n) = SOME n
| eval (Add (e1, e2)) = evalHelper ( op+ ) (e1, e2)
| eval (Sub (e1, e2)) = evalHelper ( op- ) (e1, e2)
| eval (Mul (e1, e2)) = evalHelper ( op* ) (e1, e2)
| eval (Div (e1, e2)) =
case eval e1 of
NONE => NONE
| SOME x => case eval e2 of
NONE => NONE
| SOME 0 => NONE
| SOME y => SOME (x div y)
and evalHelper binop (e1, e2) =
case eval e1 of
NONE => NONE
| SOME x => case eval e2 of
NONE => NONE
| SOME y => SOME (binop (x, y))
Here the return type is int option, which means that you most often return an int, but if you ever divide by zero, that results in "no value", so rather than raise an exception, we return NONE, which necessitates us to return SOME n when there is a result, so that the type fits in both cases.
A quick demonstration:
- eval (Div (Int 5, Int 2));
> val it = SOME 2 : int option
- eval (Div (Int 5, Int 0));
> val it = NONE : int option
- eval (Div (Int 2, Sub (Int 3, Int 3)));
> val it = NONE : int option
- eval (Div (Int 0, Int 1));
> val it = SOME 0 : int option
Here SOME 0 actually means "the result is 0", which is not the same as "cannot divide by zero."

searching an element in list in ocaml

(* function for union of two ordered sets*)
let rec search n list1 = match list1 with
[] -> false
| head :: tail when head = n -> true
| head :: tail when head != n -> search n tail
;;
(* function calls and output *)
Printf.printf("\nList = {");;
open Printf
let list1=[3;1;2;4];; (* Input first set here *)
let () = List.iter (printf " %d ") list1;;
printf("}");;
n=2;;
let u = search n list1;;
I am getting an error:
File "search.ml", line 15, characters 0-1:
Error: Unbound value n
Line 15 => "n=2;;"
Kindly inform whether it is a syntactic error or otherwise and possible remedy as well. Implementation is done on linux.
Expression n=2 compares n to 2, however n is not defined yet, so you get an error. You should use let n = 2 to bind values to names.
in OCaml to bound a value with a name one should use len name = value syntax

ML. How to correctly work with sequences

So I have this "new" two way sequence:
datatype direction = Back | Forward;
datatype 'a bseq = bNil
| bCons of 'a * (direction -> 'a bseq);
and I need a function seq2bseq : 'a seq -> 'a seq -> 'a bseq that "appends" two regular sequences into one like so:
if seqUp is 0 1 2 3 4 ... and seqDown is -1 -2 -3 -4 ... then seq2bseq will create .. -4 -3 -2 -1 0 1 2 3 4 .. . In other words the starter element is the first of seqUp(0) so if I move Back I will get to the first element of seqDown(-1) and two the second of the seqUp(1) if I move Forward.
So far I wrote the following:
fun appendq (Nil, yq) = yq
| appendq (Cons(x,xf), yq) = Cons(x,fn()=>appendq(xf(),yq));
fun seq2bseq (DownSeq) (UpSeq) =
bCons(head(UpSeq), fn (Forward) => seq2bseq appendq(head(UpSeq), DownSeq) tail(UpSeq)
| (Back) => seq2bseq tail(DownSeq) appendq(head(DownSeq), UpSeq) );
for which I get the following errors:
stdIn:28.101-28.153 Error: operator and operand don't agree [tycon mismatch]
operator domain: 'Z seq * 'Z seq -> 'Z seq
operand: 'Y seq -> 'Y seq
in expression:
seq2bseq tail
stdIn:27.5-28.155 Error: right-hand-side of clause doesn't agree with function result type [tycon mismatch]
expression: _ seq -> _ bseq
result type: _ * _ -> ('Z seq -> 'Z seq) -> _ seq -> _
in declaration:
seq2bseq = (fn arg => (fn <pat> => <exp>))
I can't figure out what's wrong(:/). Help!
Thanks!
Edit: working(?) code at: http://www.beetxt.com/mkX/.
Your type errors appear to be coming from a lack of parenthesization.
If you have functions foo and bar, and want to call foo on the result of calling bar on the value baz, then you need to write this as foo (bar baz) or foo (bar (baz)), if you prefer.
Writing foo bar(baz) will cause foo to be called with the argument bar, which will likely not type-check.
Try:
fun seq2bseq (DownSeq) (UpSeq) =
bCons(head(UpSeq),
fn Forward => seq2bseq (appendq(head(UpSeq), DownSeq)) (tail(UpSeq))
| Back => seq2bseq (tail(DownSeq)) (appendq(head(DownSeq), UpSeq))
)