Generate all words from an alphabet - list

I'd like to generate all words from a given alphabet. For example:
['a', 'b'] -> ["","a","b","aa","ba","ab","bb","aaa","baa","aba","bba","aab" ...]
I manage to implement this function by now:
myfunc :: [a] -> [[[a]]]
myfunc l = iterate fromList $ map (\x -> x : []) l
where
fromList ls = [y : ys | y <- l, ys <- ls]
But this function doesn't generate the result correctly. I want the answer to be a String to take for example only the first 5 elements -> ["","a","b","aa","ba"]. Any help how to do that?

Based on your example you do not generate sublists: you generate sequences of string from the given alphabet l.
Furthermore the signature of myfunc should be [a] -> [[a]]. Indeed the elements of the list are strings as well, so [a]s.
You can use recursive list comprehension for that:
myfunc :: [a] -> [[a]]
myfunc l = []:[(x:ys) | ys <- myfunc l, x <- l]
Which generates:
*Main> take 10 $ myfunc "ab"
["","a","b","aa","ba","ab","bb","aaa","baa","aba"]
The code works as follows, the first element we emit is the empty string (the [] part in the []:...). So this will be the first result we emit (but also the first in the recursive result).
Now in the list comprehension part, we iterate over all elements of myfunc l (so first ys is the empty list), and we prepend that element with all characters of the alphabet (a and b). Next ys will be [a] and so we prepend the characters of the alpabeth with that, and so on.

Related

List of tuples in haskell

Given a list of tuples asd :: [(Char, Char)], I want to write a function that takes in a string and returns the same string, with characters matching the first element of tuples in asd replaced with the corresponding second element.
For example, with asd = [('a', 'b'), ('c', 'd')], with input "ac", it should return "bd".
I also want to write a function that does the reverse, which when given input "bd" should return "ac".
I have a solution, but I can't use list generator and recursion.
This is my solution:
xyz :: String -> String
xyz x = concat (map y x) where y ys = [a | (b,a) <- asd, ys == b]
zyx x :: String -> String
zyx x = concat (map y x) where y ys = [a | (a,b) <- asd, ys == b]
How can I write this without recursion and list generator?
Pending clarification regarding exact specification in comments, I am assuming that you want to replace characters while keeping non-matching as-is.
To apply a function to each element of a list (a String is just [Char]), use map :: (a -> b) -> [a] -> [b]. Hence, you will need to write a map on the input string like so
xyz :: String -> String
xyz = map replace
This replace function should run through the list of tuples asd, and find the first tuple that matches. (I'm making an assumption here as it wasn't specified how to handle having more than one matching tuple.) To do this, we make use of filter :: (a -> Bool) -> [a] -> [a] to find which tuples are matching.
replace :: Char -> Char
replace c = case filter ((== c) . fst) asd of
((_, c'):_) -> c' -- found a replacement
[] -> c -- no match, don't replace character
where ((== c) . fst) compares the first element of the tuple to the character c.
Lastly, to implement the reverse function, simply do the same thing but with the replacement looking up by the second element instead, like so
zyx :: String -> String
zyx = map replace'
replace' :: Char -> Char
replace' c = case filter ((== c) . snd) asd of
((c', _):_) -> c' -- found a replacement
[] -> c -- no match, don't replace character
Reference links for fst and snd.

Is there a way to get all the possible rearrangements of a list in Haskell?

I want to create a function that rearranges the elements of a list.
For example the list [1,2,3] will produce:
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
The order isn't important.
If I write this list comprehension:
[[a,b,c] | a <- l, b <- l, c <- l, a /= b, a /= c, b /= c]
It works (where l is the desired list). Problem is I want to do this for an undefined number of list elements
Yes. The Data.List module has a permutations :: [a] -> [[a]] function to generate all permutations. This does not only work on three or more elements, but it does not use an Eq typeconstraint. If a list contains two items that are equal, then you can still consider it a different permutation when we swap the two.
We can furthermore implement such function ourself. We can first make a helper function that is given a list and returns a list of 2-tuples where the first item contains the value we "picked", and the second item a list of remaining elements:
pick :: [a] -> [(a, [a])]
pick [] = []
pick (x:xs) = (x, xs) : map prep (pick xs)
where prep (y, ys) = (y, x:ys)
For example:
Prelude> pick [1,4,2,5]
[(1,[4,2,5]),(4,[1,2,5]),(2,[1,4,5]),(5,[1,4,2])]
Next we can use recursion to each time pick an element, and recurse on the remaining elements:
perms :: [a] -> [[a]]
perms [] = [[]]
perms xs = [ p : ps | (p, ys) <- pick xs, ps <- perms ys ]
This then yields:
Prelude> perms [1,4,2,5]
[[1,4,2,5],[1,4,5,2],[1,2,4,5],[1,2,5,4],[1,5,4,2],[1,5,2,4],[4,1,2,5],[4,1,5,2],[4,2,1,5],[4,2,5,1],[4,5,1,2],[4,5,2,1],[2,1,4,5],[2,1,5,4],[2,4,1,5],[2,4,5,1],[2,5,1,4],[2,5,4,1],[5,1,4,2],[5,1,2,4],[5,4,1,2],[5,4,2,1],[5,2,1,4],[5,2,4,1]]

Haskell, zip the element of a list with its length

The next lines should show how its has to work..
[14,2,344,41,5,666] after [(14,2),(2,1),(344,3),(5,1),(666,3)]
["Zoo","School","Net"] after [("Zoo",3),("School",6),("Net",3)]
Thats my code up to now
zipWithLength :: [a] -> [(a, Int)]
zipWithLength (x:xs) = zipWith (\acc x -> (x, length x):acc) [] xs
I want to figure out what the problem in the second line is.
If you transform the numbers into strings (using show), you can apply length on them:
Prelude> let zipWithLength = map (\x -> (x, length (show x)))
Prelude> zipWithLength [14,2,344,41,5,666]
[(14,2),(2,1),(344,3),(41,2),(5,1),(666,3)]
However, you cannot use the same function on a list of strings:
Prelude> zipWithLength ["Zoo","School","Net"]
[("Zoo",5),("School",8),("Net",5)]
The numbers are not the lengths of the strings, but of their representations:
Prelude> show "Zoo"
"\"Zoo\""
Prelude> length (show "Zoo")
5
As noted in the comments, similar problems may happen with other types of elements:
Prelude> zipWithLength [(1.0,3),(2.5,3)]
[((1.0,3),7),((2.5,3),7)]
Prelude> show (1.0,3)
"(1.0,3)"
Prelude> length (show (1.0,3))
7
If you want to apply a function on every element of a list, that is a map :: (a -> b) -> [a] -> [b]. The map thus takes a function f and a list xs, and generates a list ys, such that the i-th element of ys, is f applied to the i-th element of xs.
So now the only question is what mapping function we want. We want to take an element x, and return a 2-tuple (x, length x), we can express this with a lambda expression:
mapwithlength = map (\x -> (x, length x))
Or we can use ap :: Monad m => m (a -> b) -> m a -> m b for that:
import Control.Monad(ap)
mapwithlength = map (ap (,) length)
A problem is that this does not work for Ints, since these have no length. We can use show here, but there is an extra problem with that: if we perform show on a String, we get a string literal (this means that we get a string that has quotation marks, and where some characters are escaped). Based on the question, we do not want that.
We can define a parameterized function for that like:
mapwithlength f = map (ap (,) (length . f))
We can basically leave it to the user. In case they want to work with integers, they have to call it with:
forintegers = mapwithlength show
and for Strings:
forstrings = mapwithlength id
After installing the number-length package, you can do:
module Test where
import Data.NumberLength
-- use e.g for list of String
withLength :: [[a]] -> [([a], Int)]
withLength = map (\x -> (x, length x))
-- use e.g for list of Int
withLength' :: NumberLength a => [a] -> [(a, Int)]
withLength' = map (\x -> (x, numberLength x))
Examples:
>>> withLength ["Zoo", "bear"]
[("Zoo",3),("bear",4)]
>>> withLength' [14, 344]
[(14,2),(344,3)]
As bli points out, calculating the length of a number using length (show n) does not transfer to calculating the length of a string, since show "foo" becomes "\"foo\"". Since it is not obvious what the length of something is, you could parameterise the zip function with a length function:
zipWithLength :: (a -> Int) -> [a] -> [(a, Int)]
zipWithLength len = map (\x -> (x, len x))
Examples of use:
> zipWithLength (length . show) [7,13,666]
[(7,1),(13,2),(666,3)]
> zipWithLength length ["Zoo", "School", "Bear"]
[("Zoo",3),("School",6),("Bear",4)]
> zipWithLength (length . concat) [[[1,2],[3],[4,5,6,7]], [[],[],[6],[6,6]]]
[([[1,2],[3,4],[5,6,7]],7),([[],[],[6],[6,6]],3)]

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.

Haskell:: how to compare/extract/add each element between lists

I'm trying to get each element from list of lists.
For example, [1,2,3,4] [1,2,3,4]
I need to create a list which is [1+1, 2+2, 3+3, 4+4]
list can be anything. "abcd" "defg" => ["ad","be","cf","dg"]
The thing is that two list can have different length so I can't use zip.
That's one thing and the other thing is comparing.
I need to compare [1,2,3,4] with [1,2,3,4,5,6,7,8]. First list can be longer than the second list, second list might be longer than the first list.
So, if I compare [1,2,3,4] with [1,2,3,4,5,6,7,8], the result should be [5,6,7,8]. Whatever that first list doesn't have, but the second list has, need to be output.
I also CAN NOT USE ANY RECURSIVE FUNCTION. I can only import Data.Char
The thing is that two list can have different length so I can't use zip.
And what should the result be in this case?
CAN NOT USE ANY RECURSIVE FUNCTION
Then it's impossible. There is going to be recursion somewhere, either in the library functions you use (as in other answers), or in functions you write yourself. I suspect you are misunderstanding your task.
For your first question, you can use zipWith:
zipWith f [a1, a2, ...] [b1, b2, ...] == [f a1 b1, f a2 b2, ...]
like, as in your example,
Prelude> zipWith (+) [1 .. 4] [1 .. 4]
[2,4,6,8]
I'm not sure what you need to have in case of lists with different lengths. Standard zip and zipWith just ignore elements from the longer one which don't have a pair. You could leave them unchanged, and write your own analog of zipWith, but it would be something like zipWithRest :: (a -> a -> a) -> [a] -> [a] -> [a] which contradicts to the types of your second example with strings.
For the second, you can use list comprehensions:
Prelude> [e | e <- [1 .. 8], e `notElem` [1 .. 4]]
[5,6,7,8]
It would be O(nm) slow, though.
For your second question (if I'm reading it correctly), a simple filter or list comprehension would suffice:
uniques a b = filter (not . flip elem a) b
I believe you can solve this using a combination of concat and nub http://www.haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html#v%3anub which will remove all duplicates ...
nub (concat [[0,1,2,3], [1,2,3,4]])
you will need to remove unique elements from the first list before doing this. ie 0
(using the same functions)
Padding then zipping
You suggested in a comment the examples:
[1,2,3,4] [1,2,3] => [1+1, 2+2, 3+3, 4+0]
"abcd" "abc" => ["aa","bb","cc"," d"]
We can solve those sorts of problems by padding the list with a default value:
padZipWith :: a -> (a -> a -> b) -> [a] -> [a] -> [b]
padZipWith def op xs ys = zipWith op xs' ys' where
maxlen = max (length xs) (length ys)
xs' = take maxlen (xs ++ repeat def)
ys' = take maxlen (ys ++ repeat def)
so for example:
ghci> padZipWith 0 (+) [4,3] [10,100,1000,10000]
[14,103,1000,10000]
ghci> padZipWith ' ' (\x y -> [x,y]) "Hi" "Hello"
["HH","ie"," l"," l"," o"]
(You could rewrite padZipWith to have two separate defaults, one for each list, so you could allow the two lists to have different types, but that doesn't sound super useful.)
General going beyond the common length
For your first question about zipping beyond common length:
How about splitting your lists into an initial segment both have and a tail that only one of them has, using splitAt :: Int -> [a] -> ([a], [a]) from Data.List:
bits xs ys = (frontxs,frontys,backxs,backys) where
(frontxs,backxs) = splitAt (length ys) xs
(frontys,backys) = splitAt (length xs) ys
Example:
ghci> bits "Hello Mum" "Hi everyone else"
("Hello Mum","Hi everyo","","ne else")
You could use that various ways:
larger xs ys = let (frontxs,frontys,backxs,backys) = bits xs ys in
zipWith (\x y -> if x > y then x else y) frontxs frontys ++ backxs ++ backys
needlesslyComplicatedCmpLen xs ys = let (_,_,backxs,backys) = bits xs ys in
if null backxs && null backys then EQ
else if null backxs then LT else GT
-- better written as compare (length xs) (length ys)
so
ghci> larger "Hello Mum" "Hi everyone else"
"Hillveryone else"
ghci> needlesslyComplicatedCmpLen "Hello Mum" "Hi everyone else"
LT
but once you've got the hang of splitAt, take, takeWhile, drop etc, I doubt you'll need to write an auxiliary function like bits.