Seuqences in ML (finite & infinnite) - sml

Okay,
I've got the next definition of sequence:
datatype 'a seq = Nil | Cons of 'a * (unit-> 'a seq);
I need to implement the next function:
filterq_n:('a -> bool) -> int -> 'a seq -> 'a seq
The function gets a predicate function which returns true or false, n (integer) and sequence.
The functionality:
if n<=0 return the same seq.
else return a seq that its first n elements are the first n elements in the original seq that predicate returns true for them and the rest will be the same.
For example, if the predicate is (x mod 2) and the seq is 1,2,3,4,5... and n is 3 so the new seq is
2,4,6,7,8,...
In addition, I should check another 2 options:
2.1) if the seq is finite and has less than n elements that predicate returns true for them then the new seq will contain only the elements that predicate returns true for them.
2.2) if the seq is infinite and has less than n elements that predicate returns true for them then the new seq will contain all the elements that predicate returns true for them and when trying to get the next element it will enter to an infinite loop.
My current code logically was planned for now without considering 2.1 and 2.2 (although I get errors and can find why?)
fun filter_n (predicate: 'a -> bool ) (n: int) Nil = Nil
| filter_n (predicate: 'a -> bool ) (n: int) (Cons(x, xf)) =
if(n <= 0) then Cons(x, xf)
else
if predicate x then Cons(x, fn() => filter_n predicate n-1 (xf()) )
else filter_n predicate n-1 (xf())
;
syntax errors or drastic change..I am not sure?
(also, for 2.1 ans 2.2 I just need to check that if I got (Nil and n>0) then return Nil? )
Thanks in advance for any help.

You need to wrap n-1 in parens, otherwise it's interpreted as multiple arguments. After you did that, it will compile.
However there's still a logic error in your code: You're decreasing n whether the predicate matches or not. However the specification says that you should select n elements where the predicate matches, not that you should check the predicate for n elements. So you should only decrease n if the predicate matches and keep the same n otherwise.
Once you've fixed that, your code should meet the specification (including 2.1 and 2.2).

Related

Lazy list of x, f x, f (f x),

Batteries.LazyList allows one to define lazy lists. I would like to define a lazy list consisting of x, f x, f (f x), f (f (f x)), etc.
Based on comments in the module documentation, it appears that from_loop is the function I want:
"from_loop data next creates a (possibly infinite) lazy list from the successive results of applying next to data, then to the result, etc."
This description suggests that if I wanted a lazy list of non-negative integers, for example, I could define it like this:
let nat_nums = from_loop 0 (fun n -> n + 1)
However, this fails because the signature of from_loop is
'b -> ('b -> 'a * 'b) -> 'a LazyList.t
so the next function has signature ('b -> 'a * 'b). In utop, the error message underlines n + 1 and says
Error: This expression has type int but an expression was expected of type 'a * int
I don't understand what 'a is supposed to be. Why is the next function supposed to return a pair? Why is the type of the list supposed to be a 'a LazyList.t? Shouldn't the type of the elements be the same as the type of the argument to the next function? The description of the function doesn't make the answers clear to me.
In case it's helpful, my conception of what I'm trying to do comes from Clojure's iterate. In Clojure I could create the above definition like this:
(def nat-nums (iterate (fn [n] (+ n 1)) 0))
The function passed to from_loop has to return a pair. The first element of the pair is the value you want to return. The second element of the pair is the state required to calculate the next element later on.
Your code:
(fun n -> n + 1)
Just calculates the next element of the lazy list, it doesn't return the state required for the next call. Something like this is what is wanted:
(fun n -> (n, n + 1))
(This will return a list starting with 0, which I think is what you want.)
This formulation is more flexible than your clojure example, because it allows you to maintain arbitrary state distinct from the values returned. The state is of type 'b in the type you give for from_loop.
I don't have Batteries right now, so I can't try this out. But I think it's correct based on the types.
It turns out that the function that I really wanted was LazyList.seq, not from_loop. While from_loop has its uses, seq is simpler and does what I wanted. The only trick is that you have to provide a third argument which is a termination test that returns false when the list should end. I wanted an infinite list. One can create that using use a termination function that always returns true:
let nat_nums = seq 0 (fun n -> n + 1) (fun _ -> true);;
LazyList.to_list (LazyList.take 8 nat_nums);;
- : int list = [0; 1; 2; 3; 4; 5; 6; 7]

How does one signify an infinite list to be ascending for elem checks?

I have an infinite list of primes initialized by the following list comprehension:
primes = [x | x <- [2..], 0 `notElem` map (x `mod`) [2..(x `quot` 2)]]
This allows me to make checks like 17 `elem` primes to confirm that 17 is a prime. However, when I check whether a non-prime is in the list, the program does not stop computing. I assume that this is because it does not realize that if the number cannot be found in the list before a prime that is greater than the number, it cannot be found anywhere in the list. Therefore, is there anyway in Haskell to signify to the compiler that a list contains only ascending numbers, so that an elem check will know to stop and return false if it reaches a number in the list greater than its first argument?
One possibility would be to use dropWhile:
isPrime n = (head $ dropWhile (< n) primes) == n
Sure. You can define your own OrderedList newtype, wrap the infinite list, define more efficient searching function that takes OrderedList as its argument.
newtype OrderedList a = OL [a]
member a (OL as) = case dropWhile (<a) as of
[] -> False
(x:_) -> a == x
You cannot override the behavior of elem eventhough it's a class method of Foldable, since the definition of elem only requires the underlying element type to be Eqable, namely:
member :: (Ord a, Eq a) => a -> OrderedList a -> Bool
elem :: (Eq a, Foldable t) => a -> t a -> Bool
You can verify that by the following code:
instance Foldable OrderedList where
foldMap f (OL as) = foldMap f as
elem = member -- error: Could not deduce `Ord a` arising from a use of `member`
Just a note: when your list is not infinite, you'd better consider make use of the tree-like structures (e.g. IntSet), they optimize the complexity of search operaton from O(n) to O(log(n)).
One can code it as a fold:
memberOrd :: (Eq a, Ord a) => a -> [a] -> Bool
memberOrd x = foldr (\y b -> y==x || y<x && b) False
The laziness of || makes it work on infinite lists as well.
(Clearly, we must assume that the list does not contain infinitely many elements < x. We are not suddenly able to solve undecidable problems... ;-) )
Will Ness below suggests the following variant, which performs fewer comparisons:
memberOrd x = foldr (\y b -> y<x && b || y==x) False

Walk through list using elements, but not losing elements Haskell

I am looking for a way of walking through a list, grabbing an element (in that order its given I suppose), using it with another function, then returning to that list and continuing the operation WITHOUT losing that element from the list.
In examples I've seen the only way to accomplish this would be to do the following:
counter :: (Eq a1, Num a) => a1 -> [a1] -> a
counter a [] = 0
counter a [x] = if a == x then 1 else 0
counter a (x:xs) = if a == x then counter a xs + 1 else counter a xs
permut :: Eq a => [a] -> [a] -> Bool
permut [] [] = True
permut [x] [] = False
But this gets rid of the element x from the list xs when called again both within permut. I know that this also serves to end the recursive calls/terminate the function, but I need to have the whole list available in my counter function in order for it to work. I want to simply walk through the list and keep the whole thing intact. Is this possible?
EDIT: Updated use case. I am trying to work on checking if one list is a permutation of another. My thought process is within each list two properties will hold if they are a permutation:
They will have the same number of total elements (will implement this piece later)
They will have the same number of each element
Right now my counter function works, but I am losing elements as I iterate recursively through the permut function. I don't care about efficiency, I don't mind counting the same element again and comparing it if the number shows up in the list multiple times.
Your pattern match is a bit too exhaustive, and you need to check your condition for all elements. It should look like:
permut [] ys = null ys
permut xs ys = all condition xs
where
condition x = ....
Bonus suggestion: Whenever it is the case that it is true that you find yourself writing
if ..... then True else False
you write to much.
----- Addendum:
So you found all, it does walk through the list (xs in our case) and it checks if the condition is True for all elements (of xs in our case). For example:
all even [1,2,3]
is a short way to say:
even 1 && even 2 && even 3
So, in your where clause you have condition, and it has access to the original xs and ys lists, and it is called for each element in xs. Hence, all you need to check is if the argument x of condition occurs the same number of times in xs and ys. For this, you have already counter, so it'll be a one liner.

Haskell Check if a list of Int's is complete

Not easy way to explain this, but I will try. I think i'm confusing my method with some C, but here it goes:
I want to check if a list is complete, like this:
main> check 1 [1,3,4,5]
False
main> check 1 [1,2,3,4]
True
It's a finite list, and the list doesn't have to be ordered. But inside the list there most be the number that misses to be True. In the first case it's the number 2.
This is my version, but it doesn't even compile.
check :: Eq a => a -> [a] -> Bool
check n [] = False
check n x | n/=(maximum x) = elem n x && check (n+1) x
| otherwise = False
So if I understand this correctly, you want to check to see that all the elements in a list form a sequence without gaps when sorted. Here's one way:
noGaps :: (Enum a, Ord a) => [a] -> Bool
noGaps xs = all (`elem` xs) [minimum xs .. maximum xs]
[minimum xs .. maximum xs] creates a sequential list of all values from the lowest to the highest value. Then you just check that they are all elements of the original list.
Your function doesn't compile because your type constraints are greater than what you declare them as. You say that a only needs to be an instance of Eq - but then you add something to it, which requires it to be an instance of Num. The way you use the function also doesn't make sense with the signature you declared - check [1,2,3,4] is a Bool in your example, but in the code you gave it would be Eq a => [[a]] -> Bool (if it compiled in the first place).
Do you only need this to work with integers? If not, give some example as to what "complete" means in that case. If yes, then do they always start with 1?
Here's another take on the problem, which uses a function that works on sorted lists, and use it with a sorted input.
The following will check that the provided list of n Int contains all values from 1 to n:
check :: (Num a, Ord a) => [a] -> Bool
import List
check l = check_ 1 (sort l)
where check_ n [] = True
check_ n [x] = n == x
check_ n (x:y:xs) = (x+1)==y && check_ (n+1) (y:xs)
Note the use of List.sort to prepare the list for the real check implemented in check_.

Less than function in SML

I've come across 2 confusing problems in SML and was hoping someone could help me out:
The first is a function which takes an element and a list and decides whether that element exists in the list or not, here is the code I've attempted to write:
fun member (e,L) = foldl (fn(a,b) => if (e = b) then true else false) false L;
But I get bool * 'a list --> bool but what I need is ''a * ''a list --> bool
As for the second, it also requires an element and a list but returns a list of elements less than the passed one. I'm not sure whether this should be done via map or foldr/foldl.
Any suggestions?
Thanks in advance :)
Regarding the first question, in fn (a, b) => ... a is the next element and b is the accumulator. Since you compare e with b, e is infered to have type bool. You should compare e with a, and never override b when it becomes true:
fun exists (e, L) =
foldl (fn (a, b) => e = a orelse b) false L
For the second question, you can use foldr/foldl to do so. It's similar to the first example; you start with empty list as the accumulator and prepend an element to it whenever that element is smaller than a threshold.
As a tradeoff, foldr gives you the right order but it isn't tail-recursive. On the other hand, foldl is tail-recursive but gives resulting lists in a reverse order.
to see if an element is in list or not try this:
fun elementExist(e, nil) = false
| elementExist(e, x::xs) = if e = x orelse elementExist(e, xs) then true else false;
for the second one to remove the existing element from the list:
fun elFromList(e, nil) = []
| elFromList(e, x::xs) = if e = x then elFromList(e, xs) else x::elFromList(e, xs);
Good Luck!!