steven
steven

Reputation: 37

Recursive function

I am having trouble with an exercise where I should define a function which takes as input an integer, a character and a string and returns the result of putting the character in the string at the position specified by the integer, for example, giving 3, 'a' and "haskell" to the function should result in "hasakell".

putinto :: Int -> Char -> String -> String
putinto

Upvotes: 1

Views: 416

Answers (4)

Undreren
Undreren

Reputation: 2871

I think this should be fairly easy to read. I enumerated the lines for explanation:

1. putInto :: Int -> Char -> String -> String
2. putInto 0 a xs     = a:xs
3. putInto _ a []     = [a]
4. putInto n a (x:xs) = x : putInto (n-1) a xs

What goes on here? The first line is the type signature. The second line checks if you wish to set the character at the front (ie. index 0).

The third and fourth line is for when we wish to insert it later than the 0'th index. The third line checks if the list we want to insert into is empty, in which case we just return the list containing only a.

In the fourth line we know that the first index of our string will still be the first, so we just recurse on the tail, decreasing n as needed along the way.

Upvotes: 0

Andrew
Andrew

Reputation: 31

Before writing an explicitly recursive solution to a problem involving lists in Haskell, it's worth checking to see if the same task can be accomplished using the list functions in the Prelude or Data.List. In this case splitAt can help:

splitAt 3 "haskell"
("has","kell")

Thus your problem is easily solved by splitting, consing and appending:

putInto :: Int -> Char -> String -> String
putInto n c xs = let (ys,zs) = splitAt n xs in ys ++ (c:zs)

Just for fun, the above can also be written in a point-free style using the applicative instance for (-> r):

putInto :: Int -> Char -> String -> String
putInto n c = ((++) . fst <*> (c:) . snd) . splitAt n

Upvotes: 3

Frerich Raabe
Frerich Raabe

Reputation: 94279

Think about it this way: having a list where the first element is called 'x' and the rest of the list is called 'xs' (in Haskell, this would be written as (x:xs)), you either prepend your given value to the list of the position is 0. Otherwise you call yourself recursively on the remained of the list (and decrease the poisition).

putinto :: Int -> a -> [a] -> [a]
putinto 0 value list   = value : list
putinto n value (x:xs) = x : putinto (n-1) value xs

In case it looks odd, the (x:xs) is actually a "deconstructed" list. The x represents the first element of the list, xs (the 's' means 'plural', so it's the plural of 'x') is the rest of the list.

So calling it with a zero will actually prepend the given value, as in

putinto 0 'a' "haskell"  -- yields 'ahaskell'

Calling it with two will be:

putinto 2 'a' "haskell"
-- same as 'h' : putinto 1 'a' "askell"
-- same as 'h' : 'a' : putinto 0 'a' "skell"
-- same as 'h' : 'a' : 'a' : "skell"
-- same as "haaskell"

You still need to care about error checking (what if the given position is negative, or larger than the list length?) though.

Upvotes: 6

Lukas Huzen
Lukas Huzen

Reputation: 183

int j = 3;
char a = 'a';
string x = "haskell";

string part1 = x.Substring(0, j);
string part2 = x.Substring(j);
string result = part1 + a + part2;

this wil do the trick in C#

Upvotes: 3

Related Questions