2

i want something like that:

helpPadNumbers ["123","45","1"] 4

the result should be: ["#123","##45","###1"] instead of '#' it should be ' ' (space) After my method all elements have the same length.

helpPadNumbers :: [String] -> Int -> [String]
helpPadNumbers x 0 = x
helpPadNumbers x a = map ((test1 x a) a)

test1 :: String -> Int -> String
test1 x a = (spaces1 ((a-length x))) ++ x

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = " " ++ spaces1 (n-1)

My problem is: How can i get every single element of the list separately with the map function?

Error: "Probable cause: ‘map’ is applied to too few arguments"

is there a way to fix that problem?

1 Answer 1

9

You are on the right track there - map does indeed what you want. So let's start with a working version for a quick answer:

helpPadNumbers :: [String] -> Int -> [String]
helpPadNumbers x 0 = x
helpPadNumbers x a = map (\ xs -> test1 xs a) x

have a look at the map there - your problem was basically the order and the parens.

making it look nicer

Of course that's not really Haskell style so let's reorder your arguments a bit (and remove some parens):

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers 0 xs = xs
helpPadNumbers a xs = map (test1 a) xs

test1 :: Int -> String -> String
test1 a x = spaces1 (a - length x) ++ x

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = " " ++ spaces1 (n-1)

as you can see this version make use of partial application and we don't need the lambda-expression in there. Also it looks nicer IMO

(++) is not your friend

Have a look at space1 - all you do is prepend a single space character but using lists and cocatenation - not really needed:

spaces1 :: Int -> String
spaces1 0 = ""
spaces1 n = ' ' : spaces1 (n-1)

as you can see this one uses (:) to prepend a single space character ' ' which is more performant.

Speaking of space1: there already is a function for this: replicate:

spaces1 :: Int -> String
spaces1 n = replicate n ' ' 

some further simplifications

replicate is rather forgiving (no problem with negative numbers or zero) - we don't really need the case where a = 0 above. So we can simplify further to this:

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers n xs = map (test1 n) xs

test1 :: Int -> String -> String
test1 n x = spaces1 (n - length x) ++ x

spaces1 :: Int -> String
spaces1 n = replicate n ' ' 

and I think we can fit the helper functions into a where clause:

helpPadNumbers :: Int -> [String] -> [String]
helpPadNumbers n = map spaces
  where spaces xs = replicate (n - length xs) ' ' ++ xs
example:

here is an example-use of the last version:

λ> helpPadNumbers 4 ["12345", "1234","123","12","1",""]
["12345","1234"," 123","  12","   1","    "]
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I see i have to work on my style in haskell!
no problem - it's really just a few transformations that are rather mechanical - just get your head around the types, currying and partial application - the rest will follow. BTW: some might argue my style too (some like point-free, some like it explicit, ...)
I like your approach: start with a simple fix to get the working version, then optimize (w/ explanations) until you arrive at the desired form. You're not just showing the final code, you're showing the entire path to get there. Great job!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.