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

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

Related

Getting error while defining a sequence of (all) Fibonacci numbers, in SML/NJ

here is my code:
val fibs =
let
val rec fibs_help =
fn(n, next) => Cons(n, (fn()=>fibs_help(next, n+next)) )
in
fibs_help(0, 1)
end;
val list = fibs(10)
And here is the error:
Error: unbound variable or constructor: Cons
The error message refers to a missing data type constructor, Cons. It is missing because you have no data type declaration in the mentioned code. You are probably missing a line that looks like:
datatype 'a seq = Cons of 'a * (unit -> 'a seq)
If you insert that declaration at the top of your code, you get a new error message:
! val list = fibs(10)
! ^^^^
! Type clash: expression of type
! int seq
! cannot have type
! 'a -> 'b
You get this error because you define fibs as a sequence of integers, but in the last line, you refer to fibs as a function that takes, presumably, a number of elements you wish to extract from that sequence. There is nothing wrong with the definition of the sequence. Here's how I would format the first part of the code:
val fibs =
let fun fibs_help (n, next) = Cons (n, fn () => fibs_help (next, n+next))
in fibs_help(0, 1)
end
In order to extract a concrete amount of elements from this infinite sequence into e.g. a finite list requires a little more work. Write a function take (i, s) that produces a list of the first i elements of the sequence s:
fun take (0, ...) = ...
| take (i, Cons (n, subseq_f)) = ...
The base case is when you want a list of zero elements from any sequence. Consider if/what you need to pattern match on the input sequence and what the result of this trivial case is. The recursive case is when you want a list of one or more elements from any sequence; do this by including the one element n in the result and solve a problem of the same structure but with a size one less using take, i and subseq_f.
Once this function works, you can use it to get your list of ten elements:
val ten_first = take (10, fibs)

How turn list of pair in list of int, where result int is sum of pair

I try to define function with the following protocol:
[(1,2), (6,5), (9,10)] -> [3, 11, 19]
Here is what I have now:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else (#1 hd(l)) + (#2 hd(l))::sum_pairs(tl(l))
According to type checker I have some type mismatch, but I can't figure out where exactly I'm wrong.
This code runs in PolyML 5.2:
fun sum_pairs (l : (int * int) list) =
if null l
then []
else ((#1 (hd l)) + (#2 (hd l))) :: sum_pairs(tl l)
(* ------------^-------------^ *)
The difference from yours is subtle, but significant: (#1 hd(l)) is different from (#1 (hd l)); the former doesn't do what you think - it attempts to extract the first tuple field of hd, which is a function!
While we're at it, why don't we attempt to rewrite the function to make it a bit more idiomatic? For starters, we can eliminate the if expression and the clunky tuple extraction by matching on the argument in the function head, like so:
fun sum_pairs [] = []
| sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest)
We've split the function into two clauses, the first one matching the empty list (the recursive base case), and the second one matching a nonempty list. As you can see, this significantly simplified the function and, in my opinion, made it considerably easier to read.
As it turns out, applying a function to the elements of a list to generate a new list is an incredibly common pattern. The basis library provides a builtin function called map to aid us in this task:
fun sum_pairs l = map (fn (a, b) => a + b) l
Here I'm using an anonymous function to add the pairs together. But we can do even better! By exploiting currying we can simply define the function as:
val sum_pairs = map (fn (a, b) => a + b)
The function map is curried so that applying it to a function returns a new function that accepts a list - in this case, a list of integer pairs.
But wait a minute! It looks like this anonymous function is just applying the addition operator to its arguments! Indeed it is. Let's get rid of that too:
val sum_pairs = map op+
Here, op+ denotes a builtin function that applies the addition operator, much like our function literal (above) did.
Edit: Answers to the follow-up questions:
What about arguments types. It looks like you've completely eliminate argument list in the function definition (header). Is it true or I've missed something?
Usually the compiler is able to infer the types from context. For instance, given the following function:
fun add (a, b) = a + b
The compiler can easily infer the type int * int -> int, as the arguments are involved in an addition (if you want real, you have to say so).
Could you explain what is happening here sum_pairs ((a, b)::rest) = (a + b)::sum_pairs(rest). Sorry for may be dummy question, but I just want to fully understand it. Especially what = means in this context and what order of evaluation of this expression?
Here we're defining a function in two clauses. The first clause, sum_pairs [] = [], matches an empty list and returns an empty list. The second one, sum_pairs ((a, b)::rest) = ..., matches a list beginning with a pair. When you're new to functional programming, this might look like magic. But to illustrate what's going on, we could rewrite the clausal definition using case, as follows:
fun sum_pairs l =
case l of
[] => []
| ((a, b)::rest) => (a + b)::sum_pairs(rest)
The clauses will be tried in order, until one matches. If no clause matches, a Match expression is raised. For example, if you omitted the first clause, the function would always fail because l will eventually be the empty list (either it's empty from the beginning, or we've recursed all the way to the end).
As for the equals sign, it means the same thing as in any other function definition. It separates the arguments of the function from the function body. As for evaluation order, the most important observation is that sum_pairs(rest) must happen before the cons (::), so the function is not tail recursive.

SML: How can I pass a function a list and return the list with all negative reals removed?

Here's what I've got so far...
fun positive l1 = positive(l1,[],[])
| positive (l1, p, n) =
if hd(l1) < 0
then positive(tl(l1), p, n # [hd(l1])
else if hd(l1) >= 0
then positive(tl(l1), p # [hd(l1)], n)
else if null (h1(l1))
then p
Yes, this is for my educational purposes. I'm taking an ML class in college and we had to write a program that would return the biggest integer in a list and I want to go above and beyond that to see if I can remove the positives from it as well.
Also, if possible, can anyone point me to a decent ML book or primer? Our class text doesn't explain things well at all.
You fail to mention that your code doesn't type.
Your first function clause just has the variable l1, which is used in the recursive. However here it is used as the first element of the triple, which is given as the argument. This doesn't really go hand in hand with the Hindley–Milner type system that SML uses. This is perhaps better seen by the following informal thoughts:
Lets start by assuming that l1 has the type 'a, and thus the function must take arguments of that type and return something unknown 'a -> .... However on the right hand side you create an argument (l1, [], []) which must have the type 'a * 'b list * 'c list. But since it is passed as an argument to the function, that must also mean that 'a is equal to 'a * 'b list * 'c list, which clearly is not the case.
Clearly this was not your original intent. It seems that your intent was to have a function that takes an list as argument, and then at the same time have a recursive helper function, which takes two extra accumulation arguments, namely a list of positive and negative numbers in the original list.
To do this, you at least need to give your helper function another name, such that its definition won't rebind the definition of the original function.
Then you have some options, as to which scope this helper function should be in. In general if it doesn't make any sense to be calling this helper function other than from the "main" function, then it should not be places in a scope outside the "main" function. This can be done using a let binding like this:
fun positive xs =
let
fun positive' ys p n = ...
in
positive' xs [] []
end
This way the helper function positives' can't be called outside of the positive function.
With this take care of there are some more issues with your original code.
Since you are only returning the list of positive integers, there is no need to keep track of the
negative ones.
You should be using pattern matching to decompose the list elements. This way you eliminate the
use of taking the head and tail of the list, and also the need to verify whether there actually is
a head and tail in the list.
fun foo [] = ... (* input list is empty *)
| foo (x::xs) = ... (* x is now the head, and xs is the tail *)
You should not use the append operator (#), whenever you can avoid it (which you always can).
The problem is that it has a terrible running time when you have a huge list on the left hand
side and a small list on the right hand side (which is often the case for the right hand side, as
it is mostly used to append a single element). Thus it should in general be considered bad
practice to use it.
However there exists a very simple solution to this, which is to always concatenate the element
in front of the list (constructing the list in reverse order), and then just reversing the list
when returning it as the last thing (making it in expected order):
fun foo [] acc = rev acc
| foo (x::xs) acc = foo xs (x::acc)
Given these small notes, we end up with a function that looks something like this
fun positive xs =
let
fun positive' [] p = rev p
| positive' (y::ys) p =
if y < 0 then
positive' ys p
else
positive' ys (y :: p)
in
positive' xs []
end
Have you learned about List.filter? It might be appropriate here - it takes a function (which is a predicate) of type 'a -> bool and a list of type 'a list, and returns a list consisting of only the elements for which the predicate evaluates to true. For example:
List.filter (fn x => Real.>= (x, 0.0)) [1.0, 4.5, ~3.4, 42.0, ~9.0]
Your existing code won't work because you're comparing to integers using the intversion of <. The code hd(l1) < 0 will work over a list of int, not a list of real. Numeric literals are not automatically coerced by Standard ML. One must explicitly write 0.0, and use Real.< (hd(l1), 0.0) for your test.
If you don't want to use filter from the standard library, you could consider how one might implement filter yourself. Here's one way:
fun filter f [] = []
| filter f (h::t) =
if f h
then h :: filter f t
else filter f t

OCaml: List mapping a function with 2 inputs

I have a function sqrt which takes 2 floating point values, tolerance and number and gives out square root of the number within the specified tolerance. I use approximation method to do it.
let rec sqrt_rec approx tol number =
..................;;
let sqrt tol x = sqrt_rec (x/.2.0) tol x;;
I've another function map which takes a function and a list and applies the function to all elements of the list.
let rec map f l =
match l with
[] -> []
| h::t -> f h::map f t;;
Now I'm trying to create another function all_sqrt which basically takes 1 floating point value, 1 floating point list and maps function sqrt to all the elements.
let all_sqrt tol_value ip_list = List.map sqrt tol_value ip_list;;
It is obviously giving me error. I tried making tol_value also a list but it still throws up error.
Error: This function is applied to too many arguments;
maybe you forgot a `;'
I believe i'm doing mapping wrong.
The List module contains
val map2 : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
which is used like this:
let all_sqrt tol_value ip_list = List.map2 sqrt tol_value ip_list
This sounds like homework, since you say you are limited to certain functions in your solution. So I'll try to give just some suggestions, not an answer.
You want to use the same tolerance for all the values in your list. Imagine if there was a way to combine the tolerance with your sqrt function to produce a new function that takes just one parameter. You have something of the type float -> float -> float, and you somehow want to supply just the first float. This would give you back a function of type float -> float.
(As Wes pointed out, this works because your sqrt function is defined in Curried form.)
All I can say is that FP languages like OCaml (and Haskell) are exceptionally good at doing exactly this. In fact, it's kind of hard not to do it as long as you mind the precedences of various things. (I.e., think about the parentheses.)
I don't know O'Caml, but I do know Haskell, and it looks to me like you are applying map to 3 arguments "sqrt tol_value ip_list" map only takes two arguments, and is of the type ('a -> 'b) -> 'a list -> 'b list which means it accepts a function (functions only take one input and return one output), and a list, and returns a new list.
http://en.wikipedia.org/wiki/Currying

Difficulty thinking of properties for FsCheck

I've managed to get xUnit working on my little sample assembly. Now I want to see if I can grok FsCheck too. My problem is that I'm stumped when it comes to defining test properties for my functions.
Maybe I've just not got a good sample set of functions, but what would be good test properties for these functions, for example?
//transforms [1;2;3;4] into [(1,2);(3,4)]
pairs : 'a list -> ('a * 'a) list //'
//splits list into list of lists when predicate returns
// true for adjacent elements
splitOn : ('a -> 'a -> bool) -> 'a list -> 'a list list
//returns true if snd is bigger
sndBigger : ('a * 'a) -> bool (requires comparison)
There are already plenty of specific answers, so I'll try to give some general answers which might give you some ideas.
Inductive properties for recursive functions. For simple functions, this amounts probably to re-implementing the recursion. However, keep it simple: while the actual implementation more often than not evolves (e.g. it becomes tail-recursive, you add memoization,...) keep the property straightforward. The ==> property combinator usually comes in handy here. Your pairs function might make a good example.
Properties that hold over several functions in a module or type. This is usually the case when checking abstract data types. For example: adding an element to an array means that the array contains that element. This checks the consistency of Array.add and Array.contains.
Round trips: this is good for conversions (e.g. parsing, serialization) - generate an arbitrary representation, serialize it, deserialize it, check that it equals the original.
You may be able to do this with splitOn and concat.
General properties as sanity checks. Look for generally known properties that may hold - things like commutativity, associativity, idempotence (applying something twice does not change the result), reflexivity, etc. The idea here is more to exercise the function a bit - see if it does anything really weird.
As a general piece of advice, try not to make too big a deal out of it. For sndBigger, a good property would be:
let ``should return true if and only if snd is bigger`` (a:int) (b:int) =
sndBigger (a,b) = b > a
And that is probably exactly the implementation. Don't worry about it - sometimes a simple, old fashioned unit test is just what you need. No guilt necessary! :)
Maybe this link (by the Pex team) also gives some ideas.
I'll start with sndBigger - it is a very simple function, but you can write some properties that should hold about it. For example, what happens when you reverse the values in the tuple:
// Reversing values of the tuple negates the result
let swap (a, b) = (b, a)
let prop_sndBiggerSwap x =
sndBigger x = not (sndBigger (swap x))
// If two elements of the tuple are same, it should give 'false'
let prop_sndBiggerEq a =
sndBigger (a, a) = false
EDIT: This rule prop_sndBiggerSwap doesn't always hold (see comment by kvb). However the following should be correct:
// Reversing values of the tuple negates the result
let prop_sndBiggerSwap a b =
if a <> b then
let x = (a, b)
sndBigger x = not (sndBigger (swap x))
Regarding the pairs function, kvb already posted some good ideas. In addition, you could check that turning the transformed list back into a list of elements returns the original list (you'll need to handle the case when the input list is odd - depending on what the pairs function should do in this case):
let prop_pairsEq (x:_ list) =
if (x.Length%2 = 0) then
x |> pairs |> List.collect (fun (a, b) -> [a; b]) = x
else true
For splitOn, we can test similar thing - if you concatenate all the returned lists, it should give the original list (this doesn't verify the splitting behavior, but it is a good thing to start with - it at least guarantees that no elements will be lost).
let prop_splitOnEq f x =
x |> splitOn f |> List.concat = x
I'm not sure if FsCheck can handle this though (!) because the property takes a function as an argument (so it would need to generate "random functions"). If this doesn't work, you'll need to provide a couple of more specific properties with some handwritten function f. Next, implementing the check that f returns true for all adjacent pairs in the splitted lists (as kvb suggests) isn't actually that difficult:
let prop_splitOnAdjacentTrue f x =
x |> splitOn f
|> List.forall (fun l ->
l |> Seq.pairwise
|> Seq.forall (fun (a, b) -> f a b))
Probably the only last thing that you could check is that f returns false when you give it the last element from one list and the first element from the next list. The following isn't fully complete, but it shows the way to go:
let prop_splitOnOtherFalse f x =
x |> splitOn f
|> Seq.pairwise
|> Seq.forall (fun (a, b) -> lastElement a = firstElement b)
The last sample also shows that you should check whether the splitOn function can return an empty list as part of the returned list of results (because in that case, you couldn't find first/last element).
For some code (e.g. sndBigger), the implementation is so simple that any property will be at least as complex as the original code, so testing via FsCheck may not make sense. However, for the other two functions here are some things that you could check:
pairs
What's expected when the original length is not divisible by two? You could check for throwing an exception if that's the correct behavior.
List.map fst (pairs x) = evenEntries x and List.map snd (pairs x) = oddEntries x for simple functions evenEntries and oddEntries which you can write.
splitOn
If I understand your description of how the function is supposed to work, then you could check conditions like "For every list in the result of splitOn f l, no two consecutive entries satisfy f" and "Taking lists (l1,l2) from splitOn f l pairwise, f (last l1) (first l2) holds". Unfortunately, the logic here will probably be comparable in complexity to the implementation itself.