Haskell Function to multiply elements in a list - list

dobb[] = []
dobb (x:xs) = [x * 2| x<- xs]
I am really new to haskell and started learning it this week. I want to create a function that multiplies each element in a list by 2. So the list would go from [1,2,3] to [2,4,6]. The code I have works fine, except it skips the first element of the list and goes from [1,2,3] to [4,6]. How can I make the code multiply the first element as well?
[x*2 | x<-[1..5]]
I've found this line that does what I am looking for, but I dont understand how to go from this line of code and convert it to a function that works for all lists.

I'll address your last question,
how to go from this line of code,
[x*2 | x <- [1..5]]
and convert it to a function that works for all lists[?]
This is known as generalization and is achieved by abstraction. First we name it,
foo = [x*2 | x <- [1..5]]
then we name that arbitrary piece of data we used as an example to work on,
foo = let {xs = [1..5]} in [x*2 | x <- xs]
and then we abstract over it by removing that arbitrary piece of data in the internal definition, letting it become the function parameter instead, to be specified by this, now, function's callers:
foo xs = [x*2 | x <- xs]
and there it is, the general function working on all lists, doing the same thing as it did on the specific example we used at first.

If you use the pattern (x:xs) then you unpack the list such that x is the head (first item) of the list, and xs is the tail (remaining items) of that list. For a list [1,4,2,5], x will thus refer to 1, and xs to [4,2,5].
In the list comprehension, you then use x <- xs as a generator, and thus you enumerate over the remaining elements. The x in the list comprehension is furthermore not the head of the list, but a more locally scoped variable.
You can work with list comprehension and work on the entire list, so:
dobb :: Num a => [a] -> [a]
dobb xs = [x * 2| x <- xs]
We can also work with map :: (a -> b) -> [a] -> [b] to perform the same operation on the elements:
dobb :: Num a => [a] -> [a]
dobb = map (2*)

Related

How do I filter a list without using List.filter in OCaml?

I have to write a function that, given two lists, it returns a list of the elements of the first one whose square is present in the second one (sry for my english). I can't do it recursively and i can't use List.filter.
this is what i did:
let lst1= [1;2;3;4;5];;
let lst2= [9;25;10;4];;
let filquadi lst1 lst2 =
let aux = [] in
List.map(fun x -> if List.mem (x*x) lst2 then x::aux else []) lst1;;
It works but it also prints [] when the number doesn't satisfy the if statement:
filquadi lst1 lst2 ;;
- : int list list = [[]; [2]; [3]; []; [5]]
how can I return a list of numbers instead of a list of a list of numbers?
- : int list = [2;3;5]
You can use List.concat to put things together at the end:
List.concat (List.map ...)
As a side comment, aux isn't doing anything useful in your code. It's just a name for the empty list (since OCaml variables are immutable). It would probably be clearer just to use [x] instead of x :: aux.
As another side comment, this is a strange sounding assignment. Normally the reason to forbid use of functions from the List module is to encourage you to write your own recursive solution (which indeed is educational). I can't see offhand a reason to forbid the use of recursion, but it's interesting to combine functions from List in different ways.
Your criteria don't say you can't use List.fold_left or List.rev, so...
let filter lst1 lst2 =
List.fold_left
(fun init x ->
if List.mem (x * x) lst2 then x::init
else init)
[] lst1
|> List.rev
We start with an empty list, and as we fold over the first list, add the current element only if that element appears in the second list. Because this results in a list that's reversed from its original order, we then reverse that.
If you're not supposed to use recursion, this is technically cheating, because List.fold_left works recursively, but then so does basically anything working with lists. Reimplementing the List module's functions is going to involve a lot of recursion, as can be seen from reimplementing fold_left and filter.
let rec fold_left f init lst =
match lst with
| [] -> init
| x::xs -> fold_left f (f init x) xs
let rec filter f lst =
match lst with
| [] -> []
| x::xs when f x -> x :: filter f xs
| _::xs -> filter f xs

How to shuffle a list in Haskell using random selection

I am trying to shuffle a list of any a using random numbers. The reason I ask this here is because I have already made a function and I can't figure out why exactly it isn't working.
pick :: [a] -> IO a
pick xs = do
n <- randomRIO (0, length xs - 1)
return $ xs !! n
shuffle :: [a] -> [IO a]
shuffle ls = do
x <- pick ls
let y = remove x ls
(return x) : shuffle y
-- Remove an element from a list (Only first appearance)
remove :: (Eq a) => a -> [a] -> [a]
remove _ [] = []
remove r (x:xs) = if x == r then xs else x : remove r xs
The error I get:
num.hs:31:10: error:
* Couldn't match type `IO' with `[]'
Expected type: [a]
Actual type: IO a
* In a stmt of a 'do' block: x <- pick ls
In the expression:
do x <- pick ls
let y = remove x ls
(return x) : shuffle y
In an equation for `shuffle':
shuffle ls
= do x <- pick ls
let y = ...
(return x) : shuffle y
|
31 | x <- pick ls
| ^^^^^^^
What doesn't make sense to me is that it says it received a type [a] instead of IO a for pick, but ls is defined as [a]?
If there is something fundamentally wrong with this that I just don't understand, is there another way to shuffle a list in Haskell that is this simple? Preferably without any imports.
What's happening is that the type signature for shuffle implies that its do-block has type [IO a]. This means that the monad for this do-block isn't IO as you intend, but rather the monad instance for lists [], as that's the "outermost" type constructor here. The expression pick ls is therefore required, by the do-block, to have type [t] for some type t, but the type signature for pick implies that pick ls has type IO a for some type a. GHC is complaining that it expected pick ls to have a list type [a] (because of the type of the do-block) but its actual type was IO a (because of the type signature of pick).
I believe the conceptual mistake you've made is that you're thinking of IO as a kind of modifier on a type that makes it IO-friendly. So, if IO a is an a that can be generated using an effectful IO computation, then it must be true that [IO a] is a list of as each of which can be generated using an effectful IO computation. But this is wrong!
Instead, you should think of IO a as an IO action (like a recipe) that, when executed, can produce an a. If you want a list of such as, you don't want a list of actions/recipes, each of which produces a single a (i.e., you don't want [IO a]). Instead, you want a single action/recipe that produces a list of as, so you want an IO [a].
So, shuffle should have type signature:
shuffle :: [a] -> IO [a]
Making this change will result in another error for the last expression:
(return x) : shuffle y
The issue here comes from the same conceptual mistake: you're taking a (trivial) action/recipe for generating x and trying to create a list of actions/recipes (though now shuffle y isn't a list anymore, so there's a type mismatch). Instead, you want to replace this with:
xs <- shuffle y -- use `shuffle y :: IO [a]` action to get `xs :: [a]`
return (x:xs) -- make an action to return the whole list (type `IO [a]`)
You'll also find you need to add an Eq a constraint to shuffle because it's required to invoke remove; also, this will hang unless you properly handle the empty list case. The final version of shuffle would be:
shuffle :: (Eq a) => [a] -> IO [a]
shuffle [] = return []
shuffle ls = do
x <- pick ls
let y = remove x ls
xs <- shuffle y
return (x:xs)
and that should work:
> shuffle [1..10]
[6,8,7,2,5,10,1,9,4,3]
You probably are looking for a function like:
shuffle :: [a] -> IO [a]
shuffle [] = return []
shuffle ls = do
x <- pick ls
fmap (x:) (shuffle (remove x ls))
You thus first pick an element from ls and then you recurse on the list of the list. Then we can return a list (x:xs).
The above can made more elegant. I leave this as an exercise. It is for example usually not a good idea to calculate the length of a list each iteration, since that makes the algorithm O(n2). Furthermore you might want to rewrite pick as a function that returns the item and the list after removal.

How can I find the index where one list appears as a sublist of another?

I have been working with Haskell for a little over a week now so I am practicing some functions that might be useful for something. I want to compare two lists recursively. When the first list appears in the second list, I simply want to return the index at where the list starts to match. The index would begin at 0. Here is an example of what I want to execute for clarification:
subList [1,2,3] [4,4,1,2,3,5,6]
the result should be 2
I have attempted to code it:
subList :: [a] -> [a] -> a
subList [] = []
subList (x:xs) = x + 1 (subList xs)
subList xs = [ y:zs | (y,ys) <- select xs, zs <- subList ys]
where select [] = []
select (x:xs) = x
I am receiving an "error on input" and I cannot figure out why my syntax is not working. Any suggestions?
Let's first look at the function signature. You want to take in two lists whose contents can be compared for equality and return an index like so
subList :: Eq a => [a] -> [a] -> Int
So now we go through pattern matching on the arguments. First off, when the second list is empty then there is nothing we can do, so we'll return -1 as an error condition
subList _ [] = -1
Then we look at the recursive step
subList as xxs#(x:xs)
| all (uncurry (==)) $ zip as xxs = 0
| otherwise = 1 + subList as xs
You should be familiar with the guard syntax I've used, although you may not be familiar with the # syntax. Essentially it means that xxs is just a sub-in for if we had used (x:xs).
You may not be familiar with all, uncurry, and possibly zip so let me elaborate on those more. zip has the function signature zip :: [a] -> [b] -> [(a,b)], so it takes two lists and pairs up their elements (and if one list is longer than the other, it just chops off the excess). uncurry is weird so lets just look at (uncurry (==)), its signature is (uncurry (==)) :: Eq a => (a, a) -> Bool, it essentially checks if both the first and second element in the pair are equal. Finally, all will walk over the list and see if the first and second of each pair is equal and return true if that is the case.

Need to partition a list into lists based on breaks in ascending order of elements (Haskell)

Say I have any list like this:
[4,5,6,7,1,2,3,4,5,6,1,2]
I need a Haskell function that will transform this list into a list of lists which are composed of the segments of the original list which form a series in ascending order. So the result should look like this:
[[4,5,6,7],[1,2,3,4,5,6],[1,2]]
Any suggestions?
You can do this by resorting to manual recursion, but I like to believe Haskell is a more evolved language. Let's see if we can develop a solution that uses existing recursion strategies. First some preliminaries.
{-# LANGUAGE NoMonomorphismRestriction #-}
-- because who wants to write type signatures, amirite?
import Data.List.Split -- from package split on Hackage
Step one is to observe that we want to split the list based on a criteria that looks at two elements of the list at once. So we'll need a new list with elements representing a "previous" and "next" value. There's a very standard trick for this:
previousAndNext xs = zip xs (drop 1 xs)
However, for our purposes, this won't quite work: this function always outputs a list that's shorter than the input, and we will always want a list of the same length as the input (and in particular we want some output even when the input is a list of length one). So we'll modify the standard trick just a bit with a "null terminator".
pan xs = zip xs (map Just (drop 1 xs) ++ [Nothing])
Now we're going to look through this list for places where the previous element is bigger than the next element (or the next element doesn't exist). Let's write a predicate that does that check.
bigger (x, y) = maybe False (x >) y
Now let's write the function that actually does the split. Our "delimiters" will be values that satisfy bigger; and we never want to throw them away, so let's keep them.
ascendingTuples = split . keepDelimsR $ whenElt bigger
The final step is just to throw together the bit that constructs the tuples, the bit that splits the tuples, and a last bit of munging to throw away the bits of the tuples we don't care about:
ascending = map (map fst) . ascendingTuples . pan
Let's try it out in ghci:
*Main> ascending [4,5,6,7,1,2,3,4,5,6,1,2]
[[4,5,6,7],[1,2,3,4,5,6],[1,2]]
*Main> ascending [7,6..1]
[[7],[6],[5],[4],[3],[2],[1]]
*Main> ascending []
[[]]
*Main> ascending [1]
[[1]]
P.S. In the current release of split, keepDelimsR is slightly stricter than it needs to be, and as a result ascending currently doesn't work with infinite lists. I've submitted a patch that makes it lazier, though.
ascend :: Ord a => [a] -> [[a]]
ascend xs = foldr f [] xs
where
f a [] = [[a]]
f a xs'#(y:ys) | a < head y = (a:y):ys
| otherwise = [a]:xs'
In ghci
*Main> ascend [4,5,6,7,1,2,3,4,5,6,1,2]
[[4,5,6,7],[1,2,3,4,5,6],[1,2]]
This problem is a natural fit for a paramorphism-based solution. Having (as defined in that post)
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
foldr :: (a -> b -> b) -> b -> [a] -> b
para c n (x : xs) = c x xs (para c n xs)
foldr c n (x : xs) = c x (foldr c n xs)
para c n [] = n
foldr c n [] = n
we can write
partition_asc xs = para c [] xs where
c x (y:_) ~(a:b) | x<y = (x:a):b
c x _ r = [x]:r
Trivial, since the abstraction fits.
BTW they have two kinds of map in Common Lisp - mapcar
(processing elements of an input list one by one)
and maplist (processing "tails" of a list). With this idea we get
import Data.List (tails)
partition_asc2 xs = foldr c [] . init . tails $ xs where
c (x:y:_) ~(a:b) | x<y = (x:a):b
c (x:_) r = [x]:r
Lazy patterns in both versions make it work with infinite input lists
in a productive manner (as first shown in Daniel Fischer's answer).
update 2020-05-08: not so trivial after all. Both head . head . partition_asc $ [4] ++ undefined and the same for partition_asc2 fail with *** Exception: Prelude.undefined. The combining function g forces the next element y prematurely. It needs to be more carefully written to be productive right away before ever looking at the next element, as e.g. for the second version,
partition_asc2' xs = foldr c [] . init . tails $ xs where
c (x:ys) r#(~(a:b)) = (x:g):gs
where
(g,gs) | not (null ys)
&& x < head ys = (a,b)
| otherwise = ([],r)
(again, as first shown in Daniel's answer).
You can use a right fold to break up the list at down-steps:
foldr foo [] xs
where
foo x yss = (x:zs) : ws
where
(zs, ws) = case yss of
(ys#(y:_)) : rest
| x < y -> (ys,rest)
| otherwise -> ([],yss)
_ -> ([],[])
(It's a bit complicated in order to have the combining function lazy in the second argument, so that it works well for infinite lists too.)
One other way of approaching this task (which, in fact lays the fundamentals of a very efficient sorting algorithm) is using the Continuation Passing Style a.k.a CPS which, in this particular case applied to folding from right; foldr.
As is, this answer would only chunk up the ascending chunks however, it would be nice to chunk up the descending ones at the same time... preferably in reverse order all in O(n) which would leave us with only binary merging of the obtained chunks for a perfectly sorted output. Yet that's another answer for another question.
chunks :: Ord a => [a] -> [[a]]
chunks xs = foldr go return xs $ []
where
go :: Ord a => a -> ([a] -> [[a]]) -> ([a] -> [[a]])
go c f = \ps -> let (r:rs) = f [c]
in case ps of
[] -> r:rs
[p] -> if c > p then (p:r):rs else [p]:(r:rs)
*Main> chunks [4,5,6,7,1,2,3,4,5,6,1,2]
[[4,5,6,7],[1,2,3,4,5,6],[1,2]]
*Main> chunks [4,5,6,7,1,2,3,4,5,4,3,2,6,1,2]
[[4,5,6,7],[1,2,3,4,5],[4],[3],[2,6],[1,2]]
In the above code c stands for current and p is for previous and again, remember we are folding from right so previous, is actually the next item to process.

Apply "permutations" of a function over a list

Creating the permutations of a list or set is simple enough. I need to apply a function to each element of all subsets of all elements in a list, in the order in which they occur. For instance:
apply f [x,y] = { [x,y], [f x, y], [x, f y], [f x, f y] }
The code I have is a monstrous pipeline or expensive computations, and I'm not sure how to proceed, or if it's correct. I'm sure there must be a better way to accomplish this task - perhaps in the list monad - but I'm not sure. This is my code:
apply :: Ord a => (a -> Maybe a) -> [a] -> Set [a]
apply p xs = let box = take (length xs + 1) . map (take $ length xs) in
(Set.fromList . map (catMaybes . zipWith (flip ($)) xs) . concatMap permutations
. box . map (flip (++) (repeat Just)) . flip iterate []) ((:) p)
The general idea was:
(1) make the list
[[], [f], [f,f], [f,f,f], ... ]
(2) map (++ repeat Just) over the list to obtain
[[Just, Just, Just, Just, ... ],
[f , Just, Just, Just, ... ],
[f , f , Just, Just, ... ],
... ]
(3) find all permutations of each list in (2) shaved to the length of the input list
(4) apply the permuted lists to the original list, garnering all possible applications
of the function f to each (possibly empty) subset of the original list, preserving
the original order.
I'm sure there's a better way to do it, though. I just don't know it. This way is expensive, messy, and rather prone to error. The Justs are there because of the intended application.
To do this, you can leverage the fact that lists represent non-deterministic values when using applicatives and monads. It then becomes as simple as:
apply f = mapM (\x -> [x, f x])
It basically reads as follows: "Map each item in a list to itself and the result of applying f to it. Finally, return a list of all the possible combinations of these two values across the whole list."
If I understand your problem correctly, it's best not to describe it in terms of permutations. Rather, it's closer to generating powersets.
powerset (x:xs) = let pxs = powerset xs in pxs ++ map (x :) pxs
powerset [] = [[]]
Each time you add another member to the head of the list, the powerset doubles in size. The second half of the powerset is exactly like the first, but with x included.
For your problem, the choice is not whether to include or exclude x, but whether to apply or not apply f.
powersetapp f (x:xs) = let pxs = powersetapp f xs in map (x:) pxs ++ map (f x:) pxs
powersetapp f [] = [[]]
This does what your "apply" function does, modulo making a Set out of the result.
Paul's and Heatsink's answers are good, but error out when you try to run them on infinite lists.
Here's a different method that works on both infinite and finite lists:
apply _ [] = [ [] ]
apply f (x:xs) = (x:ys):(x':ys):(double yss)
where x' = f x
(ys:yss) = apply f xs
double [] = []
double (ys:yss) = (x:ys):(x':ys):(double yss)
This works as expected - though you'll note it produces a different order to the permutations than Paul's and Heatsink's
ghci> -- on an infinite list
ghci> map (take 4) $ take 16 $ apply (+1) [0,0..]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
ghci> -- on a finite list
ghci> apply (+1) [0,0,0,0]
[[0,0,0,0],[1,0,0,0],[0,1,0,0],[1,1,0,0],[0,0,1,0],...,[1,1,1,1]]
Here is an alternative phrasing of rampion's infinite-input-handling solution:
-- sequence a list of nonempty lists
sequenceList :: [[a]] -> [[a]]
sequenceList [] = [[]]
sequenceList (m:ms) = do
xs <- nonempty (sequenceList ms)
x <- nonempty m
return (x:xs)
where
nonempty ~(x:xs) = x:xs
Then we can define apply in Paul's idiomatic style:
apply f = sequenceList . map (\x -> [x, f x])
Contrast sequenceList with the usual definition of sequence:
sequence :: (Monad m) => [m a] -> m [a]
sequence [] = [[]]
sequence (m:ms) = do
x <- m
xs <- sequence ms
return (x:xs)
The order of binding is reversed in sequenceList so that the variations of the first element are the "inner loop", i.e. we vary the head faster than the tail. Varying the end of an infinite list is a waste of time.
The other key change is nonempty, the promise that we won't bind an empty list. If any of the inputs were empty, or if the result of the recursive call to sequenceList were ever empty, then we would be forced to return an empty list. We can't tell in advance whether any of inputs is empty (because there are infinitely many of them to check), so the only way for this function to output anything at all is to promise that they won't be.
Anyway, this is fun subtle stuff. Don't stress about it on your first day :-)