Reputation: 597
I'm trying to write a function that takes a String
and an Int
and returns that string "int" times. That is:
duplicate :: String -> Int -> String
If I were to write duplicate "Hello" 3
the output should be "HelloHelloHello"
.
Upvotes: 20
Views: 15795
Reputation: 11
Again a beginners attempt, using recursion
duplicate s n = if n <= 1 then s else duplicate (n-1) s ++ s
though it is a little unclear what the function should do if n is negative or zero. So I chose to return the string itself.
Upvotes: 1
Reputation: 47392
A String
is just a synonym for a list of Char
, and the list type is a Monad
. Therefore
duplicate :: Int -> String -> String
duplicate n str = [1..n] >>= const str
Or, if you wanted to get all point-free
duplicate = (. const) . (>>=) . enumFromTo 1
Edit
As suggested in the comments
duplicate n str = [1..n] >> str
or
duplicate = (>>) . enumFromTo 1
Upvotes: 9
Reputation: 74204
You can use replicate
and concat
as follows:
duplicate :: [a] -> Int -> [a]
duplicate = flip $ (concat .) . replicate
-- or as larsmans suggested:
duplicate :: [a] -> Int -> [a]
duplicate = (concat .) . flip replicate
Then use it as duplicate "Hello" 3
.
Upvotes: 5
Reputation: 768
You can use pattern matching.
duplicate _ 0 = []
duplicate xs n = xs ++ duplicate xs (n-1)
or
duplicate xs n | n==0 = []
| otherwise = xs ++ duplicate xs (n-1)
Upvotes: 4
Reputation: 43310
Easily:
duplicate :: String -> Int -> String
duplicate string n = concat $ replicate n string
The $
is a function of type (a -> b) -> a -> b
. The language allows the functions with non-alpha-numeric names to be used in infix form (as operators). I.e., the body of the function above is absolutely identical to the following expression:
($) concat (replicate n string)
What $
does is just allows you to get rid of braces. Meaning that the above expressions are just an alternative to the following expression:
concat (replicate n string)
Upvotes: 23