Compare real list in sml - sml

For the next code I'm getting an error:
fun epoly(L:real list, x:real)=
= if L = [] then 0.0 else (epoly(tl(L:real list), x:real));;
Error:
stdIn:42.1-42.57 Error: operator and operand don't agree [equality type required]
operator domain: ''Z * ''Z
operand: real list * 'Y list
in expression:
L = nil

Since you're not actually asking a question, it is a little unclear what your intent is. Presumably this is attempted code that doesn't work and the accompanying error message, and the implicit question is "Why doesn't this code work? What am I doing wrong, and what can I do to improve it?" But really that's guesswork, and those are lazy questions, too.
Here's how your post could look like if my assumptions above are correct and you want positive feedback in the future:
I am trying to write a function that evaluates a polynomial with real coefficients L for the variable x.
It looks like:
fun epoly (L : real list, x : real) =
if L = [] then 0.0 else epoly(tl L, x)
Unfortunately I am getting a type error that I don't understand:
stdIn:1.35-1.91 Error: operator and operand don't agree [equality type required]
operator domain: ''Z * ''Z
operand: real list * 'Y list
in expression:
L = nil
What does this error mean, and if this is not the right way to evaluate a polynomial, then what would another way to accomplish the same thing look like?
The take-aways:
Write what your problem is, don't let others assume what your problem is. Making a question easily understood makes people want to answer your question, and describing your problem in words tells what you think is the problem, so that people don't try and answer the wrong question. In this case, your question could have been "Under what version of the Standard ML specification were reals removed as an eqtype?" and a sufficient answer would have been '97. But would you have been happy about that answer?
Once you know how to ask the right question, you can also better google around (e.g. search for: evaluate polynomial "standard ml"|sml) and find that there exists code from which you can let yourself inspire: here, here, here.
Format your code nicely and make sure it works. Use StackOverflow's Markdown to format your code nicely. The code that you posted contains artifacts from the interactive REPL (an extra =), so anyone who copy-pastes it into a REPL will get an error, will have to figure out where it occurred, fix it, and then start to think about what could be the problem, since you didn't say. A good rule is to test that the code you posted works by copy-pasting it once you've asked the question. One can easily forget to include a non-standard function.
An answer, assuming my rendition of your "question" somewhat lines up with your intent:
When you do if L = [] ... then you're using equality for lists of reals, which in turn relies on equality for reals, but reals can't be compared for equality. See the Q&A "Why can't I compare reals in Standard ML?" You can test if a list of reals is empty without comparing reals by doing e.g.:
fun epoly (L, x) =
if null L then 0.0 else epoly (tl L, x)
This is because the standard library function null uses pattern matching on lists but does not address the list's elements, whereas = assumes that elements may have to be compared. Even though that never happens in practice in the example L = [], this is still an error in the type system.
If you were comparing reals for equality, consider using an epsilon test. Besides that, consider using pattern matching instead of hd and tl because those functions can fail and crash because they're partial:
fun epoly ([], x) = 0.0
| epoly (c::cs, x) = epoly (cs, x)
All this function does is throw away its second argument x, traverse its first argument, c::cs, and do nothing with each coefficient c. Presumably, in order to evaluate a polynomial, you must do something to coefficient c and x before doing the same thing recursively on the remaining coefficients cs and x, and then somehow compose those.

Related

Haskell - Why is Alternative implemented for List

I have read some of this post Meaning of Alternative (it's long)
What lead me to that post was learning about Alternative in general. The post gives a good answer to why it is implemented the way it is for List.
My question is:
Why is Alternative implemented for List at all?
Is there perhaps an algorithm that uses Alternative and a List might be passed to it so define it to hold generality?
I thought because Alternative by default defines some and many, that may be part of it but What are some and many useful for contains the comment:
To clarify, the definitions of some and many for the most basic types such as [] and Maybe just loop. So although the definition of some and many for them is valid, it has no meaning.
In the "What are some and many useful for" link above, Will gives an answer to the OP that may contain the answer to my question, but at this point in my Haskelling, the forest is a bit thick to see the trees.
Thanks
There's something of a convention in the Haskell library ecology that if a thing can be an instance of a class, then it should be an instance of the class. I suspect the honest answer to "why is [] an Alternative?" is "because it can be".
...okay, but why does that convention exist? The short answer there is that instances are sort of the one part of Haskell that succumbs only to whole-program analysis. They are global, and if there are two parts of the program that both try to make a particular class/type pairing, that conflict prevents the program from working right. To deal with that, there's a rule of thumb that any instance you write should live in the same module either as the class it's associated with or as the type it's associated with.
Since instances are expected to live in specific modules, it's polite to define those instances whenever you can -- since it's not really reasonable for another library to try to fix up the fact that you haven't provided the instance.
Alternative is useful when viewing [] as the nondeterminism-monad. In that case, <|> represents a choice between two programs and empty represents "no valid choice". This is the same interpretation as for e.g. parsers.
some and many does indeed not make sense for lists, since they try iterating through all possible lists of elements from the given options greedily, starting from the infinite list of just the first option. The list monad isn't lazy enough to do even that, since it might always need to abort if it was given an empty list. There is however one case when both terminates: When given an empty list.
Prelude Control.Applicative> many []
[[]]
Prelude Control.Applicative> some []
[]
If some and many were defined as lazy (in the regex sense), meaning they prefer short lists, you would get out results, but not very useful, since it starts by generating all the infinite number of lists with just the first option:
Prelude Control.Applicative> some' v = liftA2 (:) v (many' v); many' v = pure [] <|> some' v
Prelude Control.Applicative> take 100 . show $ (some' [1,2])
"[[1],[1,1],[1,1,1],[1,1,1,1],[1,1,1,1,1],[1,1,1,1,1,1],[1,1,1,1,1,1,1],[1,1,1,1,1,1,1,1],[1,1,1,1,1,"
Edit: I believe the some and many functions corresponds to a star-semiring while <|> and empty corresponds to plus and zero in a semiring. So mathematically (I think), it would make sense to split those operations out into a separate typeclass, but it would also be kind of silly, since they can be implemented in terms of the other operators in Alternative.
Consider a function like this:
fallback :: Alternative f => a -> (a -> f b) -> (a -> f e) -> f (Either e b)
fallback x f g = (Right <$> f x) <|> (Left <$> g x)
Not spectacularly meaningful, but you can imagine it being used in, say, a parser: try one thing, falling back to another if that doesn't work.
Does this function have a meaning when f ~ []? Sure, why not. If you think of a list's "effects" as being a search through some space, this function seems to represent some kind of biased choice, where you prefer the first option to the second, and while you're willing to try either, you also tag which way you went.
Could a function like this be part of some algorithm which is polymorphic in the Alternative it computes in? Again I don't see why not. It doesn't seem unreasonable for [] to have an Alternative instance, since there is an implementation that satisfies the Alternative laws.
As to the answer linked to by Will Ness that you pointed out: it covers that some and many don't "just loop" for lists. They loop for non-empty lists. For empty lists, they immediately return a value. How useful is this? Probably not very, I must admit. But that functionality comes along with (<|>) and empty, which can be useful.

let rec for values and let rec for functions in ocaml

What is the best intuition for why the first definition would be refused, while the second one would be accepted ?
let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x
let rec a x = b x (* oki doki *)
and b x = a x
Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?
Verifying that recursive definitions are valid is a very hard thing to do.
Basically, you want to avoid patterns in this kind of form:
let rec x = x
In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.
Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.
You can have an outlook of the rules here. Here is an excerpt (emphasis mine):
It will be accepted if each one of expr1 … exprn is statically constructive with respect to name1 … namen, is not immediately linked to any of name1 … namen, and is not an array constructor whose arguments have abstract type.
As you can see, direct recursive variable binding is not permitted.
This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.

Questions on SML type ckecking and inference

First of all, since the question is somehow related to a school project I don't think that posting my code is appropriate. Plus, as I explain later on I only have a modified version of the code in question.
And I explain myself. I should implement a version of Dijkstra's algorithm using a priority queue. I thought that a simple functional way to do so is define a dijkstra function with inputs the queue and the targeted node and a helper function to enqueue the nodes that are neighbors to the element of the list that was just dequeued. Unfortunately, the helper function did't typecheck - Unresolved Flex Record.
So far it may seem that the code is important but allow me to add one more
detail. Since the graph was 4-canonical(meaning each node has exactly four neighbors) I represented it as a matrix using modulus arithmetic. In order to simplify my algorithm I used this fact to rewrite it and use 4 extra helper functions - one for each move possible - instead of four ifs inside the first helper function. Each of the four-move function returns true if we should visit this node (meaning the cost we will need this way is smaller than the current cost needed) and false if not. And the first helper simply returns a tuple of four booleans variables. Finally, I copied the enqueue code that wasn't working in my first try into the body of the dijkstra code and suddenly it did typecheck.
I understand that it may still be unclear and perhaps you can only speculated about what was going on. But I am truly very puzzled.I searched this site and SML basis as well and found that this kind of error occurs in the following case:
f (x,y,z) = ...
where z isn't used so the checker can't deduct what it is.
I am sure this is not the case in my problem since I just copy-paste the code(not a very good technique I know but ok). Hence, I concluded that the problem was the typechecker not working with functions calls. I searched again and found a Hindley Miller algorithm explanation. And from what I understood every time it encounters and a function will assume is a->b as the first step and later on will go to the definition of the function and complete the task. So I was back to square one and decided to ask this question here looking for a better understanding of type inference or for a hint of what has going on.
P.S. 1) Even though I tried my best to explain the question I it is still unclear or too broad let me know and I will delete,no problem.
P.S. 2) A smaller and simpler question: I read that #1 is not adviceable to take the 1st element of a tuple and sometimes it doesn't even typecheck
and instead it should be used pattern matching. Could you explain that?
P.S. 3) Someone may wonder why I asked this question since I solved the problem with my second try. Personally, I don't consider solved but hidden.
Thanks in advance and sorry for the size of the question.
Links:
SML/NJ Errors
P.S. 2)
Hindley-Miller
UPDATED: After some extra searching I have a guess about what was wrong. I was implementing a priority queue not customized for my problem but more general. So, the inference of the priority queue type was taking place when I first enqueued an element. But after enqueueing my source node and calling dijkstra the queue would be empty once more (my dijsktra was dequeueing the first element checking if it is the target node) and the first call of the helper function that add nodes would have an empty queue as one of its arguments. Perhaps the empty queue has no type and that was causing the error?
I'm taking a guess at what you're asking.
I have a function enqueue that does not work in one context, but it does work in another. Why? It uses the #1 macro, and I read that #1 is not adviceable to take the 1st element of a tuple and sometimes it doesn't even typecheck and instead it should be used pattern matching.
In Standard ML, #1 is a macro. It behaves like a function, but unlike functions, it is overloaded for any tuple/record with a 1 field in it. If you do not specify what kind of tuple you're passing to a function, using #1 will not disambiguate this. For example,
- fun f pair = #1 pair;
! Toplevel input:
! fun f pair = #1 pair;
! ^^
! Unresolved record pattern
But giving it the type (either through explicit type annotation, or in a context where the type can be inferred by other means) works well.
- fun f (pair : int * int) = #1 pair;
> val f = fn : int * int -> int
I don't know if I'd label #1 as a definite no-go and pattern matching as the only option, [edit: ... but this Stack Overflow answer that Ionuț G. Stan linked to has some arguments.]
There are advantages and disadvantages with both. Alternatively you can make unambiguous getters that only work on the type of tuple you're working with. For example,
fun fst (x, _) = x
fun snd (_, y) = y

Define a rule to determine if a list contains a given member

I have recently started learning prolog, and facing a problem with this question:
Define a rule to determine if a list contains a given member.
I searched all over stack overflow to get some links to understand this problem better and write solutions for it but couldn't find anything. Could anyone of you advice to solve this particular problem?
My Approach:
Iterative over the list and see if your member matches with head:
on(Item,[Item|Rest]). /* is my target item on the list */
on(Item,[DisregardHead|Tail]):-
on(Item,Tail).
Do you think my approach is correct?
What you have is indeed a "correct" implementation. The standard name for a predicate that does that is member/2, and is available (under that name) in any Prolog, and should be quite easy to find once you know its name.
Some things to note however. First, with the classical definition (this is exactly as in "The Art of Prolog" by Sterling and Shapiro, p. 58, and identical to yours):
member_classic(X, [X|Xs]).
member_classic(X, [Y|Ys]) :-
member_classic(X, Ys).
If you try to compile this, you will get singleton errors. This is because you have named variables that appear only once in their scope: the Xs in the first clause and the Y in the second. This aside, here is what the program does:
?- member_classic(c, [a,b,c,x]).
true ;
false.
?- member_classic(c, [c]).
true ;
false.
?- member_classic(X, [a,b,c]).
X = a ;
X = b ;
X = c ;
false.
In other words, with this definition, Prolog will leave behind a choice point even when it is quite obvious that there could not be further solutions (because it is at the end of the list). One way to avoid this is to use a technique called "lagging", as demonstrated by the SWI-Prolog library implementation of member/2.
And another thing: with your current problem statement, it might be that this is considered undesirable behaviour:
?- member_classic(a, [a,a,a]).
true ;
true ;
true ;
false.
There is another predicate usually called member_check/2 or memberchk/2 which does exactly what you have written, namely, succeeds or fails exactly once:
?- memberchk(a, [a,a,a]).
true.
?- memberchk(a, [x,y,z]).
false.
It has, however, the following behaviour when the first argument is a variable that might be undesirable:
?- memberchk(X, [a,b,c]).
X = a. % no more solutions!
There are valid uses for both member/2 and memberchk/2 IMHO (but interestingly enough, some people might argue otherwise).
Yes, your solution is correct and works in all directions. Nice!
Notes:
Your solution is in fact more general than what the task asks for. This is a good thing! The task, in my view, is badly worded. First of all, the first clause is not a rule, but a fact. It would have been better to formulate the task like: "Write a Prolog program that is true if a term occurs in a list." This leaves open other use cases that a good solution will also automatically solve, such as generating solutions.
This common predicate is widely known as member/2. Just like your solution, it also works in all directions. Try for example ?- member(E, Ls).
The name for the predicate could be better. A good naming convention for Prolog makes clear what each argument means. Consider for example: element_list/2, and start from there.

How does pattern matching works with lists

I just start learning haskell and pattern matching. I just don't understand how it implemented, is the [] and (x:_) evaluates to the different type and the function implementations for this pattern recognized because of polymorphism, or I just wrong and there is another technique used.
head' :: [a] -> a
head' [] = error "Can't call head on an empty list, dummy!"
head' (x:_) = x
Or lets consider this pattern matching function:
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
I think I wrong because each list with different number of elements can't have deferent type. Can you explain me how haskell knows which pattern is correct for some function implementation? I understand how it works logically but not deep. Explain it to me please.
There's a bit of a level of indirection between the syntax in Haskell and the implementation at runtime. The list syntax that you see in most source is actually a bit of sugar for what is actually a fairly regular data type. The following two lines are equivalent:
data List a = Nil | Cons a (List a)
data [a] = [] | a : [a] -- pseudocode
So when you type in [a,b,c] this translates into the internal representation as (a : (b : (c : []))).
The pattern matching you'll see at the top level bindings in are also a bit of syntactic sugar ( sans some minor details ) for case statements which deconstruct the data types onto the right hand side of the case of the pattern match. The _ symbol is a builtin for the wildcard pattern which matches any expression ( so long as the pattern is well-typed ) but does add a variable to the RHS scope.
head :: [a] -> a
head x = case x of
(a : _) -> a
I think I wrong because each list with different number of elements can't have deferent type. Can you explain me how haskell knows which pattern is correct for some function implementation?
So to answer your question [] and (x:_) are both of the same type (namely [a] or List a in our example above). The list datatype is also recursive so all recursive combinations of Cons'ing values of type a have the same type, namely [a].
When the compiler typechecks the case statement it runs along each of the LHS columns and ensures that all the types are equivalent or can be made equivalent using a process called unification. The same is done on the right hand side of the cases.
Haskell "knows" which pattern is correct by trying each branch sequentially and unpacking the matched value to see if it has the same number of cons elements as the pattern and then proceeding to the branch which does, or failing with a pattern match error if none match. The same process is done for any pattern matching on data types, not just lists.
There are two separate sets of checks:
in compile time (before the program is run) the compiler simply checks that the types of the cases conform to the function's signature and that the calls to the function conform to the function's signature.
In runtime, when we have access to the actual input, a similar, but different, set of checks is executed: these checks take the * actual* input (not its type) at hand and determine which of the cases matches it.
So, to answer your question: the decision is made in compile time where we have not only the type but also the actual value.