Q:

read data from a list of strings

i have a data structure like this
data Something = Something Integer String String

and i want to convert
["Something", "3", "text", "42"] 

to the data. 
for now, i have
altRead :: Read a => [String] -> a
altRead = read . unwords . hack
    where 
        hack = map (\x -> if isNumber x then x else "\"" ++ x ++ "\"")
        isNumber = foldl (\b c -> isDigit c && b) True 

but i forgot, that some numbers could be strings in the data structure. 
is there a simple solution for this or do i need to write a alternative read typeclass? 

A:

With what you have, you don't really need to make it a typeclass. You can just do:
readSomething :: [String] -> Maybe Something
readSomething [_, n, s1, s2] = Just $ Something (read n) s1 s2
readSomething _              = Nothing

or, if you want to disambiguate on the first word:
data Something = Something Integer String String
               | SomethingToo String Integer

readSomething :: [String] -> Maybe Something
readSomething ["Something", n, s1, s2] = Just $ Something (read n) s1 s2
readSomething ["SomethingToo", s, n]   = Just $ SomethingToo s (read n)
readSomething _                        = Nothing

A:

You're writing a tiny parser atop some lexed tokens. You can't really implement a Read instance since read :: Read a => String -> a and you want to do [String] -> a for a == Something. You can take advantage of Read instances that already exist, though, to bootstrap parsing your Integer, for instance.
So let's try it. We'll parse a Something from the list of tokens.
import Safe -- gives us readMay :: Read a => String -> Maybe a

parseSomething :: [String] -> Maybe Something
parseSomething ("Something":strInt:stra:strb:_) = 
  do int <- readMay strInt
     return $ Something int stra strb
parseSomething _ = Nothing

We could do it a little more compactly using Maybe as an Applicative, too
import Control.Applicative

parseSomething :: [String] -> Maybe Something    
parseSomething ("Something":strInt:stra:strb:_) = 
  Something <$> readMay strInt <*> pure stra <*> pure strb
parseSomething _ = Nothing

Really, we should probably return any unconsumed tokens as well so we can continue parsing.
parseSomething :: [String] -> (Maybe Something, [String])
parseSomething ("Something":strInt:stra:strb:rest) = 
  (Something <$> readMay strInt <*> pure stra <*> pure strb, rest)
parseSomething rest = (Nothing, rest)

The reason I bring in all this structure to your parse is that this starts to head toward the space of parser combinators like Parsec. Whenever you've got a need for a complicated Read it begins to become useful to look at some of the really nice parsing libraries in Haskell.

