0

I need to create my own words functions. It takes string and puts into list where ever there is space. For example string "i need help" would result in ["i","need","help"]. The definitions must be exactly

anything :: String -> [String]

I currently came up with stupid solution which look like this ( also it doesn't work)

test :: String -> [String]
test d = beforep d : (test (afterp d)) : []

beforep :: String -> String
beforep d = takeWhile (/=' ') d
afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[] then []
      else tail(dropWhile (/=' ') d)

test -> uses tail recursion

beforep -> get everything till first space

afterp -> gets everything after space

Any ideas ? If you have any other solutions to this problem it would help. Thank you

2
  • This is a words function from Prelude Commented Oct 29, 2013 at 14:02
  • yes but i cant use the words function. I need to write it without the words function. Commented Oct 29, 2013 at 14:10

1 Answer 1

5

You've very nearly got it. If I attempt to run your code as is, I get:

test.hs:2:23:
    Couldn't match expected type `Char' with actual type `String'
    Expected type: String
      Actual type: [String]
    In the return type of a call of `test'
    In the first argument of `(:)', namely `(test (afterp d))'

So examine line 2:

test d = beforep d : (test (afterp d)) : []
--                                      ^
-- This is the problem -----------------|

The type of the cons operator is:

(:) :: a -> [a] -> [a]

Your test function returns a [String] already, you don't want to try to cons it onto an empty list. That would imply that the return type would be [[String]].

Try this instead:

test d = beforep d : (test (afterp d))

After that change, it compiles, but when you run test "i need help" you get the infinite list:

["i","need","help","","","","","","","",""...

The problem is that you need to include a base case in test that stops when you pass it an empty list. Here's the working code:

test :: String -> [String]
test [] = []
test d = beforep d : (test (afterp d))

beforep :: String -> String
beforep d = takeWhile (/=' ') d

afterp :: String -> String
afterp d = if (dropWhile (/=' ') d)==[]     -- Slightly reformatted
             then []                        -- to improve readability,
             else tail(dropWhile (/=' ') d) -- no real change.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much, great explanation. Exactly what i needed u just made my day ^^

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.