Assuming a function that "gets" 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.
numFromString :: [Char] -> ???
I suppose there is several possibilities.
My first idea is to use a type parameter.
main :: IO ()
main =
do
sLine <- getLine
print $ numFromString sLine
numFromString :: (Show a, Read a) => String -> (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
...but we cannot just provide an Integer where a type variable is expected or can we?.
My second idea is to use type class
main :: IO ()
main =
do
sLine <- getLine
print $ ((numFromString sLine) :: (Maybe Integer))
-- ^^^^^^^^^^^^^^^ I have to decide in advance which type I want to get
class (Show a, Read a) => XClass a where
numFromString :: String -> (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
...but this doesnt work as well, when we use numFromString, do we?.
My third idea is to use a sum kind of data type.
main :: IO ()
main =
do
sLine <- getLine
print $ numFromString sLine
data X = XInt Int | XInteger Integer | XNone
deriving Show
numFromString :: String -> X
numFromString ('I':'n':'t':'e':'g':'e':'r':rs) = XInteger (read rs)
numFromString ('I':'n':'t':rs) = XInt (read rs)
numFromString _ = XNone
Is there a more elegant way?
Would generic programming help?
How would it look like?