title: Creating different types from an unknown sequence, in Haskell?
body: <p>Assuming a function that &quot;gets&quot; a sequence of information (e.g. a list of characters), and shall create different types from it, where its type depends on the input sequence, which represents the content - and assuming the types are already given.</p>
  <pre><code>numFromString :: [Char] -&gt; ???
  </code></pre>
  <p>I suppose there is several possibilities.</p>
  <p>My first idea is to use a type parameter.</p>
  <pre><code>main :: IO ()
  main =
      do
          sLine &lt;- getLine
          print $ numFromString sLine
  
  numFromString :: (Show a, Read a) =&gt; String -&gt; (Maybe a)
  numFromString ('I':'n':'t':'e':'g':'e':'r':rs) = Just ((read rs) :: Integer)
  --                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this does not work
  numFromString ('I':'n':'t':rs) = Just ((read rs) :: Int)
  numFromString _ = Nothing
  </code></pre>
  <p>...but we cannot just provide an Integer where a type variable is expected or can we?.</p>
  <p>My second idea is to use type class</p>
  <pre><code>main :: IO ()
  main = 
      do
          sLine &lt;- getLine
          print $ ((numFromString sLine) :: (Maybe Integer))
          --                                ^^^^^^^^^^^^^^^ I have to decide in advance which type I want to get
  
  class (Show a, Read a) =&gt; XClass a where
      numFromString :: String -&gt; (Maybe a)
  
  instance XClass Int where
      numFromString ('I':'n':'t':rs) = Just ((read rs) :: Int)
      numFromString _ = Nothing
  
  instance XClass Integer where
      numFromString ('I':'n':'t':'e':'g':'e':'r':rs) = Just ((read rs) :: Integer)
      numFromString _ = Nothing
  </code></pre>
  <p>...but this doesnt work as well, when we use numFromString, do we?.</p>
  <p>My third idea is to use a sum kind of data type.</p>
  <pre><code>main :: IO ()
  main =
      do
          sLine &lt;- getLine
          print $ numFromString sLine
  
  data X = XInt Int | XInteger Integer | XNone
      deriving Show
  
  numFromString :: String -&gt; X
  numFromString ('I':'n':'t':'e':'g':'e':'r':rs) = XInteger (read rs)
  numFromString ('I':'n':'t':rs) = XInt (read rs)
  numFromString _ = XNone
  </code></pre>
  <p>Is there a more elegant way?</p>
  <p>Would generic programming help?</p>
  <p>How would it look like?</p>