The problem is that the final spaces are consumed by the spaces
in the argument to many
,
list = char '(' *> many (spaces *> some letter) <* spaces <* char ')'
-- ^^^^^^ that one
and then the parser expects some letter
but finds a closing parenthesis and thus fails.
To solve it, consume spaces only after tokens,
list = char '(' *> spaces *> many (some letter <* spaces) <* char ')'
that works as desired:
$ runghc lisplists.hs
Testing "()":
[]
Testing "(hello)":
["hello"]
Testing "(hello world)":
["hello","world"]
Testing "( hello world)":
["hello","world"]
Testing "(hello world )":
["hello","world"]
Testing "( )":
[]