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?
Haskell also incorporates polymorphic types---types that are universally quantified in some way over all types. Polymorphic type expressions essentially describe families of types. For example, (forall a)[a] is the family of types consisting of, for every type a, the type of lists of a.
The Nil constructor is an empty list. It contains no objects. So any time you're using the [] expression, you're actually using Nil . Then the second constructor concatenates a single element with another list.
In Haskell, every statement is considered as a mathematical expression and the category of this expression is called as a Type. You can say that "Type" is the data type of the expression used at compile time. To learn more about the Type, we will use the ":t" command.
The fields within a Haskell data type can be accessed either positionally or by name using field labels. Consider a data type for a two-dimensional point: data Point = Pt Float Float. The two components of a Point are the first and second arguments to the constructor Pt. A function such as.
Your sum type approach looks like the right way to me.
For examples of this in the wild:
{
for objects, [
for lists, "
for strings, etc. aeson
, a popular Haskell JSON parser, uses a sum type that can represent each of these.cborg
uses a sum type to capture all the possibilities.sgf
library uses a sum type to capture the possibilities....and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With