This is a question from my homework thus tips would be much likely appreciated.
I am learning Haskell this semester and my first assignment requires me to write a function that inputs 2 string (string1
and string2
) and returns a string that is composed of (the repeated) characters of first string string1
until a string of same length as string2
has been created.
I am only allowed to use the Prelude function length
.
For example: take as string1
"Key"
and my name "Ahmed"
as string2
the function should return "KeyKe"
.
Here is what I've got so far:
makeString :: Int -> [a] -> [a]
makeString val (x:xs)
| val > 0 = x : makeString (val-1) xs
| otherwise = x:xs
Instead of directly giving it two strings i am giving it an integer value (since i can subtitute it for length later on), but this is giving me a runtime-error:
*Main> makeString 8 "ahmed"
"ahmed*** Exception: FirstScript.hs: (21,1)-(23,21) : Non-exhaustive patterns in function makeString
I think it might have something to do my list running out and becoming an empty list(?).
A little help would be much appreciated.
I think this code is enough to solve your problem:
extend :: String -> String -> String
extend src dst = extend' src src (length dst)
where
extend' :: String -> String -> Int -> String
extend' _ _ 0 = []
extend' [] src size = extend' src src size
extend' (x:xs) src size = x : extend' xs src (size - 1)
The extend'
function will cycle the first string until is is consumed then will begin to consume it again.
You can also make it using take
and cycle
like functions:
repeatString :: String -> String
repeatString x = x ++ repeatString x
firstN :: Int -> String -> String
firstN 0 _ = []
firstN n (x:xs) = x : firstN ( n - 1 ) xs
extend :: String -> String -> String
extend src dst = firstN (length dst) (repeatString src)
or a more generic version
repeatString :: [a] -> [a]
repeatString x = x ++ repeatString x
firstN :: (Num n, Eq n ) => n -> [a] -> [a]
firstN 0 _ = []
firstN n (x:xs) = x : firstN ( n - 1 ) xs
extend :: [a] -> [b] -> [a]
extend _ [] = error "Empty target"
extend [] _ = error "Empty source"
extend src dst = firstN (length dst) (repeatString src)
which is capable of taking any type of lists:
>extend [1,2,3,4] "foo bar"
[1,2,3,4,1,2,3]