Related
I want to obtain a list of some of the rotations of the following string "I want to break free tonight". The constraint is that a rotation can not begin with the words "to" or "tonight". So the list of rotations is ["I want to break free today", "want to break free tonight I", "break free tonight I want to", "free tonight I want to break"].
I wrote the following functions:
rotate :: [l] -> [l]
rotate [] = []
rotate (x:xs) = (x:xs) ++ head(x:xs)
rotate1 :: [a] -> [[a]]
rotate1 xs = take (length xs) (iterate rotate xs)
main = do
print $ rotate1(words("I want to break free tonight"))
Running this code, I obtained all possible rotations, but they form a list of lists having elements like ["want", "I", "to", "break", "free", "tonight"] which is different from the string "want I to break free tonight". Also, I would want to see how I can drop the rotations that begin with the words "to", "tonight". I tried to use the filter function for the second part but I did not manage to solve the problem. Any help/hint is appreciated. I notice that I am a beginner in Haskell.
Running this code…
The code doesn't run. It has type errors.
First of all, let's fix the formatting so it's easier to read, and remove the extra parentheses
rotate :: [l] -> [l]
rotate [] = []
rotate (x:xs) = (x:xs) ++ head (x:xs)
rotate1 :: [a] -> [[a]]
rotate1 xs = take (length xs) (iterate rotate xs)
main = print $ rotate1 (words "I want to break free tonight")
This is weird:
rotate (x:xs) = (x:xs) ++ head (x:xs)
First of all, x:xs is the entire list, and x is the head of the list. For example, rotate [1, 2, 3] becomes:
rotate [1, 2, 3] = let x = 1
xs = [2, 3]
in (x:xs) ++ head (x:xs)
rotate [1, 2, 3] = (1:[2, 3]) ++ head (1:[2, 3])
rotate [1, 2, 3] = [1, 2, 3] ++ head [1, 2, 3]
rotate [1, 2, 3] = [1, 2, 3] ++ 1
-- type error
But ++ needs a list on both sides. What you probably want here is:
rotate (x:xs) = xs ++ [x]
Which gives us:
rotate [1, 2, 3] = let x = 1
xs = [2, 3]
in xs ++ [x]
rotate [1, 2, 3] = [2, 3] ++ [1]
rotate [1, 2, 3] = [2, 3, 1]
This is the same as:
rotate x = tail x ++ [head x]
For the rest of your problem… the filter should be straightforward since there is a filter function which does exactly what you need, and the unwords function turns lists of words back into strings.
You want the function intercalate :: [a] -> [[a]] -> [a] in Data.List.
From the hackage docs:
intercalate :: [a] -> [[a]] -> [a]
intercalate xs xss is equivalent to (concat (intersperse xs xss)). It
inserts the list xs in between the lists in xss and concatenates the
result.
In ghci
> import Data.List
> intercalate " " ["want", "I", "to", "break", "free", "tonight"]
> "want I to break free tonight"
I am new to Haskell, now I have a question here.
If I have a list [[1,2],[3,4],[5,6]], and I want use a function like searchList x = 3, then output 4, how to dual with it?
Use the filter high order function:
search :: [[Int]] -> Int -> Int
search list n = head (head (filter (\(x:xs) -> x == n) list))
What this search function does is to filter the elements of the passed list of lists, selecting only the ones which have the passed value n as head. Then takes only one (The first, thats why the first (right) head is used), and then extracts the first element of that list (Using head again).
If you want to store a list of pairs, I suggest you to use tuples instead of lists as elements of the list.
EDIT: As people suggested in comments, if you use tuples there is a function lookup on the prelude that implements this kind of searching.
So what you have a list of lists and you want to search it, find the element that matches [x,y] and return y.
searchList x (y:ys) = if x == head y then last y else searchList x ys
searchList x [] = -1
Which behaves like so:
Main> :load searchlist.hs
Main> searchList 3 [ [1, 2], [3, 4], [5, 6] ]
4
Main> searchList 5 [ [1, 2], [3, 4], [5, 6] ]
6
Main> searchList 6 [ [1, 2], [3, 4], [5, 6] ]
-1
As an aside it is uncommon to use lists in Haskell if you want a fixed width, like the pairs in your list. It would be more Haskell-ish to use a list of tuples, like so.
searchListTuples x (y:ys) = if x == fst y then snd y else searchListTuples x ys
searchListTuples x [] = -1
Which of course behaves very similarly:
Main> searchListTuples 3 [ (1,2), (3,4), (5,6) ]
4
Main> searchListTuples 5 [ (1,2), (3,4), (5,6) ]
6
Main> searchListTuples 6 [ (1,2), (3,4), (5,6) ]
-1
Try with :
searchList x y = last $ head $ dropWhile (\[a,_]->a/=x) y
Or, in pointfree notation:
searchList = ((last . head) .) . dropWhile . (. head) . (/=)
I like this recursive function, but a "-1" as a bad value is not a normal Haskell idiom. Use Maybe.
searchListTuples x (y:ys) = if x == fst y then Just (snd y) else SearchListTuples x ys
searchListTuples x [] = Nothing
I have a given list, e.g. [2, 3, 5, 587] and I want to have a complete list of the combination. So want something like [2, 2*3,2*5, 2*587, 3, 3*5, 3*587, 5, 5*587, 587]. Since I am on beginner level with Haskell I am curious how a list manipulation would look like.
Additionally I am curious if the computation of the base list might be expensive how would this influence the costs of the function? (If I would assume the list has limit values, i.e < 20)
Rem.: The order of the list could be done afterwards, but I have really no clue if this is cheaper within the function or afterwards.
The others have explained how to make pairs, so I concern myself here with getting the combinations.
If you want the combinations of all lengths, that's just the power set of your list, and can be computed the following way:
powerset :: [a] -> [[a]]
powerset (x:xs) = let xs' = powerset xs in xs' ++ map (x:) xs'
powerset [] = [[]]
-- powerset [1, 2] === [[],[2],[1],[1,2]]
-- you can take the products:
-- map product $ powerset [1, 2] == [1, 2, 1, 2]
There's an alternative powerset implementation in Haskell that's considered sort of a classic:
import Control.Monad
powerset = filterM (const [True, False])
You could look at the source of filterM to see how it works essentially the same way as the other powerset above.
On the other hand, if you'd like to have all the combinations of a certain size, you could do the following:
combsOf :: Int -> [a] -> [[a]]
combsOf n _ | n < 1 = [[]]
combsOf n (x:xs) = combsOf n xs ++ map (x:) (combsOf (n - 1) xs)
combsOf _ _ = []
-- combsOf 2 [1, 2, 3] === [[2,3],[1,3],[1,2]]
So it seems what you want is all pairs of products from the list:
ghci> :m +Data.List
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- bs ]
[6,10,1174,15,1761,2935]
But you also want the inital numbers:
ghci> [ a * b | a:bs <- tails [2, 3, 5, 587], b <- 1:bs ]
[2,6,10,1174,3,15,1761,5,2935,587]
This uses a list comprehension, but this could also be done with regular list operations:
ghci> concatMap (\a:bs -> a : map (a*) bs) . init $ tails [2, 3, 5, 587]
[2,6,10,1174,3,15,1761,5,2935,587]
The latter is a little easier to explain:
Data.List.tails produces all the suffixes of a list:
ghci> tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587],[]]
Prelude.init drops the last element from a list. Here I use it to drop the empty suffix, since processing that causes an error in the next step.
ghci> init [[2,3,5,587],[3,5,587],[5,587],[587],[]]
[[2,3,5,587],[3,5,587],[5,587],[587]]
ghci> init $ tails [2, 3, 5, 587]
[[2,3,5,587],[3,5,587],[5,587],[587]]
Prelude.concatMap runs a function over each element of a list, and combines the results into a flattened list. So
ghci> concatMap (\a -> replicate a a) [1,2,3]
[1, 2, 2, 3, 3, 3]
\(a:bs) -> a : map (a*) bs does a couple things.
I pattern match on my argument, asserting that it matches an list with at least one element (which is why I dropped the empty list with init) and stuffs the initial element into a and the later elements into bs.
This produces a list that has the same first element as the argument a:, but
Multiplies each of the later elements by a (map (a*) bs).
You can get the suffixes of a list using Data.List.tails.
This gives you a list of lists, you can then do the inner multiplications you want on this list with a function like:
prodAll [] = []
prodAll (h:t) = h:(map (* h) $ t)
You can then map this function over each inner list and concatenate the results:
f :: Num a => [a] -> [a]
f = concat . map prodAll . tails
So I am writing a program to generate a list of prime numbers in haskell. I create two functions shown below:
{-
Given a list of prime numbers, this function will
add the next prime number to the list. So, given the
list [2, 3], it will return [2, 3, 5]
-}
nextPrime xs = xs ++ [lastVal + nextCounts]
where
lastVal = (head . reverse) $ xs
isNextPrime y = 0 `elem` ( map ( y `mod`) xs )
nextVals = (map isNextPrime [lastVal, lastVal+1 ..] )
nextCounts = length $ takeWhile (\x -> x) nextVals
allPrimes xs = allPrimes np
where
np = nextPrime xs
Now the function 'nextPrime' is doing what it is supposed to do. However, when I do a call to allPrimes as shown below:
take 5 $ allPrimes [2,3]
The program goes into an infinite loop. I thought Haskells "lazy" features were supposed to take care of all this? What am I missing??
If you start evaluating the expression on paper you can see why laziness doesn't help here. Start with your expression:
take 5 $ allPrimes [2,3]
First, attempt to evaluate the allPrimes expression:
allPrimes [2, 3]
which becomes
allPrimes np
where
np = nextPrime [2, 3]
put the things from the where clause into the expression and it becomes
allPrimes (nextPrime [2, 3])
Now, evaluate nextPrime [2, 3] (you can do this in ghci since that function works) and get [2, 3, 5], which you can replace in the previous expression, and it becomes
allPrimes [2, 3, 5]
repeat the above and it becomes
allPrimes [2, 3, 5, 7]
and there is your problem! allPrimes never evaluated to any values, it evaluates to allPrimes applied to longer and longer lists. To see where laziness does work, try evaluating on paper a function like zip from the Prelude:
zip :: [a] -> [b] -> [(a,b)]
zip (a:as) (b:bs) = (a,b) : zip as bs
zip [1, 2, 3] ['a', 'b', 'c']
a becomes 1, as becomes [2, 3], b becomes 'a', bs becomes ['b', 'c'] so you get
(1, 'a') : zip [2, 3] ['b', 'c']
The difference here is that there is a list with a value, then the rest of the list is an expression. In your allPrimes function, you just keep getting more expressions.
For more information, look into Weak Head Normal Form however if you are new to Haskell I recommend you get comfortable with the syntax and with the basics of "Thinking in Haskell" before you start looking at things like WHNF.
I'd read Drew's answer for a good explanation of what's going wrong, but for a quick demonstration for how to make this work,
nextPrime xs = xs ++ [lastVal + nextCounts]
where
lastVal = (head . reverse) $ xs
isNextPrime y = 0 `elem` ( map ( y `mod`) xs )
-- ^ Style note, this name is super misleading, since it returns
-- false when the number is prime :)
nextVals = (map isNextPrime [lastVal, lastVal+1 ..] )
nextCounts = length $ takeWhile (\x -> x) nextVals
allPrimes xs = last np : allPrimes np
where np = nextPrime xs
Now we're constructing the list as we go, and haskell is lazy so it can grab the last element of np before evaluating the allPrimes np. In other words head (a : infiniteLoop) is a, not an infinite loop.
However this is really innefficient. Lists are singly linked in Haskell so last is O(n) as opposed to O(1) in something like Python. And ++ is also costly, O(n) for the length of the first list.
Instead
nextPrime xs = lastVal + nextCounts
where lastVal = head xs
isNextPrime = 0 `elem` map (y `rem`) xs
nextVals = map isNextPrime [lastVal ..]
nextCount = length $ takeWhile id nextVals
allPrimes xs = p : allPrimes (p:xs)
where p = nextPrime xs
So we keep the list reversed to avoid those costly traversals. We can also simplify nextPrime
import Data.Maybe
nextPrime xs = fromJust nextPrime
where isPrime y = not $ 0 `elem` map (rem y) xs
nextPrime = find isPrime [head xs ..]
Where we just search the list for the first element which is prime and add it to our list. The fromJust is normally bad, if there were no next primes we'd get an error. But since we know mathematically that there will always be a next prime, this is safe.
In the end, the code looks like
import Data.Maybe
import Data.List
nextPrime xs = fromJust nextPrime
where isPrime y = 0 `notElem` map (rem y) xs
nextPrime = find isPrime [head xs ..]
allPrimes xs = p : allPrimes (p:xs)
where p = nextPrime xs
To evaluate it, call allPrimes [2].
An even cleaner way to do this would be to have a function isPrime that returns whether a number is prime or not. And then just to have
allPrimes = filter isPrime [1..]
But I'll leave that to the curious reader.
As Drew pointed out, your function allPrimes doesn't profit from lazyness since we never have acess to what it calculates. This is because the list we want to peek into is an argument of allPrimes, not a return value.
So we need to expose the list allPrimes is building, and still keep a function call that will infinitely build the following value of this list.
Well, since allPrimes is the re-application of itself over and over, we just need a function that exposes the intermediate values. And we have one!
iterate f a == [a, f (f a),...]
So with iterate and nextPrime, we could build the following (rather strange) functions:
-- nextPrime renamed as nextPrimeList
infiniteListofListofPrimes = iterate nextPrimeList [2,3]
primeN n = (infiniteListofListofPrimes !! n) !! n
takeN n = take n (infiniteListofListofPrimes !! n)
We are generating our primes, but it's not looking great. We would rather have [primes], not redundant [[some primes]].
The next step is building the list on WHNF:
elem1:elem2:aux
where aux = newvalue:aux
Where aux will calculate the newvalue and leave everything in place for the next one.
For that we need nextPrime sticking to generating one new prime:
nextPrime xs = lastVal + nextCounts
And finding the aux that can build listOfPrimes forever.
I came up with this:
infiniteListofPrimes = 2:3:aux 2
where aux n = nextPrime (take n infiniteListofPrimes):(aux (n+1))
I am new to both Haskell and programming. My question about binding in pattern-matched, recursive functions. For instance, suppose I have a function which checks whether a given list (x:xs) is a sublist of another list, (y:ys). My initial thought, following the examples in my textbook, was:
sublist [] ys = True
sublist xs [] = False
sublist (x:xs) (y:ys)
| x == y = sublist xs ys
| x /= y = sublist (x:xs) ys
This works on test data, e.g.,
sublist [1, 2, 3] [1, 2, 4, 1, 2, 3]
where I expected it to fail. I expect it to fail, since
sublist [1, 2, 3] [1, 2, 4, 1, 2, 3]
= sublist [2, 3] [2, 4, 1, 2, 3]
= sublist [3] [4, 1, 2, 3]
at which point, I thought, [3] = 3:[] will be matched with (x:xs) in sublist, and [4, 1, 2, 3] will be matched with (y:ys) in sublist. How, then, is sublist working?
Edit: Thanks to everyone here, I think I've solved my problem. As noted, I was ("subconsciously") wanting sublist to backtrack for me. Using the last answer (BMeph) posted as a guide, I decided to approach the problem differently, in order to solve the "binding problem," i.e., the "backtracking" problem.
subseq :: (Eq a) => [a] -> [a] -> Bool
subseq [] _ = True
subseq _ [] = False
subseq (x:xs) (y:ys) =
-- subseq' decides whether the list bound to (x:xs) = M is a prefix of the list
-- bound to L = (y:ys); it recurses through L and returns a Bool value. subseq
-- recurses through M and L, returning a disjunction of Bool
-- values. Each recursive call to subseq passes M and ys to subseq', which
-- decides whether M is a prefix of the **current list bound to ys**.
let subseq' :: (Eq a) => [a] -> [a] -> Bool
subseq' [] _ = True
subseq' _ [] = False
subseq' (x:xs) (y:ys) = (x == y) && subseq' xs ys
in subseq' (x:xs) (y:ys) || subseq (x:xs) ys
It is working because:
[3] is matched as x:xs as 3:[],
[4, 1, 2, 3] is matched as y:ys as 4:[1,2,3]
3/=4 so sublist (x:xs) ys is evaluated, which eventually is True
trace:
sublist [1, 2, 3] [1, 2, 4, 1, 2, 3]
= sublist [2, 3] [2, 4, 1, 2, 3]
= sublist [3] [4, 1, 2, 3]
= sublist [3] [1, 2, 3]
= sublist [3] [2, 3]
= sublist [3] [3]
= sublist [] [] = True
sublist [1, 2, 3] [1, 2, 4, 1, 2, 3]
= sublist [2, 3] [2, 4, 1, 2, 3]
= sublist [3] [4, 1, 2, 3]
= sublist [3] [4, 1, 2, 3]
= sublist (3:[]) (4:[1,2,3]) -- Since 3 /= 4, we take sublist (x:xs) ys
= sublist (3:[]) [1,2,3]
= sublist (3:[]) (1:[2,3])
= sublist (3:[]) [2,3]
= sublist (3:[]) (2:[3])
= sublist (3:[]) [3]
= sublist [] []
= True
sublist checks if heads of lists are equal. If yes, then it removes them and proceeds (sublist xs ys). If no, it removes head from the second list (sublist (x:xs) ys). This way it "finds" the following association:
1 2 3
| | |
| | \-----\
| | |
1 2 4 1 2 3
In other words, to check sublist [1,2,3] ys for some list ys it pops elements from ys as long as they are not 1. Then it pops elements as long as they are not 2. Then it pops elements as long as they are not 3. If [1,2,3] is exhausted, then it reports True; if ys is exhausted, it reports False.
Debug.Trace is your friend. With sublist instrumented as
sublist [] ys = trace ("A: [] " ++ show ys) True
sublist xs [] = trace ("B: " ++ (show xs) ++ " []") False
sublist (x:xs) (y:ys)
| x == y = trace (info "C" "==")
sublist xs ys
| x /= y = trace (info "D" "/=")
sublist (x:xs) ys
where info tag op =
tag ++ ": " ++ (show x) ++ " " ++ op ++ " " ++ (show y) ++
"; xs=" ++ (show xs) ++ ", ys=" ++ show ys
you see what's happening, namely that it's repeatedly throwing away the head of the second list until it finds a match:
*Main> sublist [1, 2, 3] [1, 2, 4, 1, 2, 3]
C: 1 == 1; xs=[2,3], ys=[2,4,1,2,3]
C: 2 == 2; xs=[3], ys=[4,1,2,3]
D: 3 /= 4; xs=[], ys=[1,2,3]
D: 3 /= 1; xs=[], ys=[2,3]
D: 3 /= 2; xs=[], ys=[3]
C: 3 == 3; xs=[], ys=[]
A: [] []
True
Another tool that will help you implement sublist correctly is Test.QuickCheck, a library that automatically creates test data for use in verifying properties that you specify.
For example, say you want sublist to treat xs and ys as sets and determine whether the former is a subset of the latter. We can use Data.Set to specify this property:
prop_subsetOf xs ys =
sublist xs ys == fromList xs `isSubsetOf` fromList ys
where types = (xs :: [Int], ys :: [Int])
This says sublist should be equivalent to the definition on the right. The prop_ prefix is a popular convention for naming test properties to be used with QuickCheck.
Running it also identifies a failure case:
*Main> quickCheck prop_subsetOf
*** Failed! Falsifiable (after 6 tests):
[0,0]
[0]
I think where you may be misunderstanding, is that (when you first wrote the function) you assumed that in your check x /= y = sublist (x:xs) ys you (sub-consciously?) assumed that the function would backtrack and re-do your function with the tail of the original second list, not the tail of whichever piece of the list you're using when it doesn't match.
One nice (and unsettling) thing about Haskell is just how ridiculously powerful it is.
For an example, here's how what you wanted should have looked:
sublist [] ys = True
sublist xs [] = False
sublist (x:xs) (y:ys) | x /= y = False
| otherwise = sublist xs ys || sublist (x:xs) ys
which will check for all of the pieces of the first list. The "official" definition for the function (look up "isInfixOf" in your documentation) has a few extra functions that basically means the same thing.
Here's another way write it, that looks more "explanatory" to my eyes:
sublist [] ys = True
sublist xs [] = False
sublist xs ys = (xs == take (length xs) ys) || sublist xs (tail ys)
YuppieNetworking and sdcwc have already explained how the matching works. So your sublist searches for a sublist in the same sense as subsequence (not necessarily the same items in a row, there can be anything in between).
I want to note that you can often avoid explicit recursion to remove unnecessary items from the front of the list with dropWhile. Also, I wanted to give an example how to check if two lists have the same prefixes (you need this to check if the second list contains items of the first one in a row).
The first example is similar to your function, it allows for items in between, but it uses dropWhile to remove items in front of ys:
-- Test:
-- map ("foo" `subListOf`) ["kungfoo", "f-o-o!", "bar"] == [True,True,False]
[] `subListOf` _ = True
(x:xs) `subListOf` ys =
let ys' = dropWhile (/= x) ys -- find the first x in ys
in case ys' of
(_:rest) -> xs `subListOf` rest
[] -> False
The second example looks for a "dense" sublist:
-- Test:
-- map ("foo" `denseSubListOf`) ["kungfoo!", "-f-o-o-"] == [True,False]
[] `denseSubListOf` _ = True
_ `denseSubListOf` [] = False
xs `denseSubListOf` ys =
let ps = zip xs ys in
(length ps == length xs && all (uncurry (==)) ps) -- same prefix of xs and ys
|| xs `denseSubListOf` (tail ys) -- or search further
Please note that to check that the second list contains all the first one in the beginning I compare elements pair by pair (I zip them together to do it).
It is easier to explain by example:
zip [1,2,3] [1,2,3,4,5] -- gives [(1,1), (2,2), (3,3)], 4 and 5 are truncated
uncurry (==) -- an equivalent of (\(a,b) -> a == b)
all -- gives True iff (uncurry (==)) is True for all pairs
length ps == length xs -- this is to ensue that the right list is long enough