How to check if a value exists in a list in smlnj - smlnj

I'm working on some homework and I need to create a function that checks if a value exists in a list. If it does it will return true, otherwise it returns false. I have an idea of how to do it but I keep getting errors. I think it may be due to my lack of knowledge of syntax and style as this is my first time coding in sml.
I created the function exist and am passing a value and list in as a tuple.
fun exist (x, []) =
if x = hd ([]) then true
else if x = tl ([]) then true
else false;
Sorry if this code is laughably incorrect but I get the error message:
" stdIn:2.6 Warning: calling polyEqual
stdIn:3.11 Warning: calling polyEqual
stdIn:1.6-4.11 Warning: match nonexhaustive
(x,nil) => ...
val exist = fn : ''a list * 'b list -> bool "
and I'm not really sure how to fix this. Any help would be great.

Your function is pattern-matching on [], so it can only ever match the empty list.
Also, hd [] and tl [] are both errors since the empty list has neither head nor tail.
Further, if some_condition then true else false is equivalent to some_condition.
(And if some_condition then false else true is equivalent to not some_condition.)
Logical expressions are usually more readable than chains of conditionals.
And you forgot to recurse; you need to use exist on the tail of the list if the first element is not what you're looking for.
Either stick to pattern matching:
fun exist (_, []) = false
| exist (x, y::ys) = x = y orelse exist (x, ys)
or don't use it:
fun exist (x, xs) = not (null xs) andalso (x = hd xs orelse exist (x, tl xs))
Pattern matching is often the most readable solution and gives a clear picture of the various cases.
(You seem to have mixed the two forms, treating [] as an identifier rather than a type constructor.)

Related

Second Element of a List

From the Book programming in Scala I got the following line of code:
val second: List[ Int] => Int = { case x :: y :: _ => y }
//warning: match may not be exhaustive.
It states that this function will return the second element of a list of integers if the list is not empty or nil. Stil this part is a bit awkward to me:
case x :: y :: _
How does this ecxactly work? Does this mathches any list with at least 2 Elements and than return the second? If so can somebody still explain the syntax? I understood that :: is invoked on the right operand. So it could be written as
(_.::(y)).::(X)
Still I than don't get why this would return 2
val second: List[ Int] => Int = { case x :: y :: _ => y }
var x = List(1,2)
second(x) //returns 2
In the REPL, you can type:
scala> val list = "a" :: "b" :: Nil
list: List[String] = List(a, b)
which is to be read from right to left, and means take the end of a List (Nil), prepend String "b" and to this List ("b" :: Nil) prepend String a, a :: ("b" :: Nil) but you don't need the parens, so it can be written "a" :: "b" :: Nil.
In pattern matching you will more often see:
... list match {
case Nil => // ...
case x :: xs => // ...
}
to distinguish between empty list, and nonempty, where xs might be a rest of list, but matches Nil too, if the whole list is ("b" :: Nil) for example, then x="b" and xs=Nil.
But if list= "a" :: "b" :: Nil, then x="a" and xs=(b :: Nil).
In your example, the deconstruction is just one more step, and instead of a name like xs, the joker sign _ is used, indicating, that the name is probably not used and doesn't play a role.
The value second is of function type, it takes List[Int] and returns Int.
If the list has first element ("x"), and a second element ("y"), and whatever comes next (we don't care about it), we simply return the element "y" (which is the second element of the list).
In any other case, the function is not defined. You can check that:
scala> val second: PartialFunction[List[Int], Int] = {
| case x :: y :: _ => y
| }
second: PartialFunction[List[Int],Int] = <function1>
scala> second.isDefinedAt(List(1,2,3))
res18: Boolean = true
scala> second.isDefinedAt(List(1,2))
res19: Boolean = true
scala> second.isDefinedAt(List(0))
res20: Boolean = false
First of all. When you think about pattern matching you should think about matching a structure.
The first part of the case statement describes a structure. This structure may describe one or more things (variables) which are useful to deriving your result.
In your example, you are interested in deriving the second element of a list. A shorthand to build a list in Scala is to use :: method (also called cons). :: can also be used to describe a structure in case statement. At this time, you shouldn't think about evaluation of the :: method in first part of case. May be that's why you are saying about evaluation of _.::(y).::(x). The :: cons operator help us describe the structure of the list in terms of its elements. In this case, the first element (x) , the second element (y) and the rest of it (_ wildcard). We are interested in a structure that is a list with at least 2 elements and the third can be anything - a Nil to indicate end of list or another element - hence the wildcard.
The second part of the case statement, uses the second element to derive the result (y).
More on List and Consing
List in Scala is similar to a LinkedList. You know about the first element called head and start of the rest of the list. When traversing the linked list you stop if the rest of the list is Nil. This :: cons operator helps us visualise the structure of the linked list. Although Scala compile would actually be calling :: methods evaluating from right to left as you described _.::(y).::(x)
As an aside, you might have already noticed that the Scala compiler might be complain that your match isn't exhaustive. This means that this second method would work for list of any size. Because there isn't any case statement to describe list with zero or one element. Also, as mentioned in comments of previous answers, if you aren't interested in first element you can describe it as a wildcard _.
case _ :: y :: _ => y
I hope this helped.
If you see the structure of list in scala its head::tail, first element is treated as head and all remaining ones as tail(Nil will be the last element of tail). whenever you do x::y::_, x will match the head of the list and remaining will be tail and again y will match the head of the next list(tail of first list)
eg:
val l = List(1,2,3,4,5)
you can see this list in differnt ways:
1::2::3::4::5::Nil
1::List(2,3,4,5)
1::2::List(2,3,4,5)
and so on
So try matching the pattern. In your question y will give the second element

Logic on a recursive method

One of my exercises requires me to write a recursive method in which a list is given, and it returns the same list with only every other element on it.
for example : List {"a", "b", "c"} would return
List{"a","c"}
I am writing in scala, and I understand that it has built in library but I am not supposed to use those. I can only use if/else, helper methods,and patterns.
How could I parse thru a list using head and tail only?
so far I have this:
def removeLetter(list:List[String]):List[String]=list match{
case Nil => Nil
case n::rest=>
if (n == rest){ // I understand that this doesn't quite work.
tail
}
else
head::removeLetter(tail)
}
}
I am looking for the logic and not code.
Using pattern matching, you can also deconstruct a list on it's first two elements in the same way you're doing with your n::rest construction. Just remember to also take lists with uneven length into account.
You correctly stated one base-case to the recursion: In case of an empty list, the result is again the empty list. case Nil => Nil
There is a second base-case: A list containing a single element is again the list itself. case x :: Nil => x :: Nil
You can formulate the recursive step as follows: Given a list with at least two elements, the result is a list containing the first element, followed by every other element of the list after the second element. case x :: y :: z => x :: removeLetter(z) (Note that here, x and y are both of type String while z is of type List[String])
Remark: If you wanted to, you could also combine both base-cases, as in both cases, the input to the function is its output.

Scala code analyzer targets case variable names that are identical to the outer matched varables - "suspicous shadowing"

In the following code snippet in which the outer match vars (x,y) are case matched by (xx,yy):
scala> val (x,y) = (1,2)
x: Int = 1
y: Int = 2
scala> (x,y) match {
| case (xx:Int, yy:Int) => println(s"x=$x xx=$xx")
| }
x=1 xx=1
We could have also written that code as follows:
scala> (x,y) match {
| case (x:Int, y:Int) => println(s"x=$x y=$y")
| }
x=1 y=2
In this latter case the Scala Code Analyzers will inform us:
Suspicious shadowing by a Variable Pattern
OK. But is there any situation where we could end up actually misusing the inner variable (x or y) in place of the original outer match variables?
It seems this is purely stylistic? No actual possibility for bugs? If so i would be interested to learn what the bugs could be.
This could be confusing:
val x = Some(1)
val y = Some(2)
(x, y) match {
case (Some(x), Some(y)) => println(s"x=$x y=$y")
}
x and y have different types depending on whether you are inside or outside of the match. If this code wasn't using simply Option, and was several lines longer, it could be rather difficult to reason about.
Could any bugs arise from this? None that I can think of that aren't horribly contrived. You could for example, mistake one for another.
val list = List(1,2,3)
list match {
case x :: y :: list => list // List(3) and not List(1,2,3)
case x :: list => list // List with 1 element, should the outer list have size 2
case _ => list // Returns the outer list when empty
}
Not to mention what a horrible mess that is. Within the match, list sometimes refers to an inner symbol, and sometimes the outer list.
It's just code that's unnecessarily complicated to read and understand, there are no special bugs that could happen.

Correct "empty" return value for List[List[X]]

If I have a function List[A] => List[List[A]] and need to return an "empty" value, is there a theoretical preference between the following
a) Nil
b) List(Nil)
... or does it depend on the function?
For a concrete example, I could implement a function to split a list into sublists of length n or less as follows:
def sublists[A](xs: List[A], n: Int): List[List[A]] = {
val (ys, zs) = xs.splitAt(n)
if (zs.isEmpty) ys :: Nil
else ys :: sublists(zs, n)
}
If xs is empty this returns List(Nil). Do I need to include a check on whether xs is empty, returning Nil, for this function to be correct?
Without doubt, the correct empty value for a List is the empty List, no matter what the type of the List elements is.
The same is true for more elaborated types. A set containing the empty set is very different from an empty set, and so forth.
Think of it like this: A list result allows you to ask: how many results do we have? If you use a list with an empty List as empty value, then the answer would be incorrectly 1.
I would stick with Nil, aka List(). For example,
sublists(1 :: 2 :: 3 :: 4 :: Nil), 2)
returns
List(1 :: 2 :: Nil, 3 :: 4 :: Nil)
and not
List(1 :: 2 :: Nil, 3 :: 4 :: Nil, Nil)
The terminal Nil is usually chopped off. So for consistency I would keep sublists(Nil) -> List().
I don't know the context, so I don't feel comfortable being definitive. In general, I think the answer is context-dependent. In the abstract, I'd definitely prefer Nil as a client-code writer - in writing a closure over the results, I don't think I'd be expecting an empty sublist.
Rearranging to put the null-check before the splitAt will do the trick.

Explain some scala code - beginner

I've encountered this scala code and I'm trying to work out what its doing except the fact it returns an int. I'm unsure of these three lines :
l match {
case h :: t =>
case _ => 0
Function :
def iterate(l: List[Int]): Int =
l match {
case h :: t =>
if (h > n) 0
case _ => 0
}
First, you define a function called iterate and you specified the return type as Int. It has arity 1, parameter l of type List[Int].
The List type is prominent throughout functional programming, and it's main characteristics being that it has efficient prepend and that it is easy to decompose any List into a head and tail. The head would be the first element of the list (if non-empty) and the tail would be the rest of the List(which itself is a List) - this becomes useful for recursive functions that operate on List.
The match is called pattern matching.. it's essentially a switch statement in the C-ish languages, but much more powerful - the switch restricts you to constants (at least in C it does), but there is no such restriction with match.
Now, your first case you have h :: t - the :: is called a "cons", another term from functional programming. When you create a new List from another List via a prepend, you can use the :: operator to do it.
Example:
val oldList = List(1, 2, 3)
val newList = 0 :: oldList // newList == List(0, 1, 2, 3)
In Scala, operators that end with a : are really a method of the right hand side, so 0 :: oldList is the equivalent of oldList.::(0) - the 0 :: oldList is syntactic sugar that makes it easier to read.
We could've defined oldList like
val oldList = 1 :: 2 :: 3 :: Nil
where Nil represents an empty List. Breaking this down into steps:
3 :: Nil is evaluated first, creating the equivalent of a List(3) which has head 3 and empty tail.
2 is prepended to the above list, creative a new list with head 2 and tail List(3).
1 is prepended, creating a new list with head 1 and tail List(2, 3).
The resulting List of List(1, 2, 3) is assigned to the val oldList.
Now when you use :: to pattern match you essentially decompose a List into a head and tail, like the reverse of how we created the List above. Here when you do
l match {
case h :: t => ...
}
you are saying decompose l into a head and tail if possible. If you decompose successfully, you can then use these h and t variables to do whatever you want.. typically you would do something like act on h and call the recursive function on t.
One thing to note here is that your code will not compile.. you do an if (h > n) 0 but there is no explicit else so what happens is your code looks like this to the compiler:
if (h > n) 0
else { }
which has type AnyVal (the common supertype of 0 and "nothing"), a violation of your Int guarentee - you're going to have to add an else branch with some failure value or something.
The second case _ => is like a default in the switch, it catches anything that failed the head/tail decomposition in your first case.
Your code essentially does this:
Take the l List parameter and see if it can be decomposed into a head and tail.
If it can be, compare the head against (what I assume to be) a variable in the outer scope called n. If it is greater than n, the function returns 0. (You need to add what happens if it's not greater)
If it cannot be decomposed, the function returns 0.
This is called pattern matching. It's like a switch statement, but more powerful.
Some useful resources:
http://www.scala-lang.org/node/120
http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-4