For my own understanding, I want to define a function in Haskell that takes two arguments- either both Integers, or both Chars. It does some trivial examination of the arguments, like so:
foo 1 2 = 1
foo 2 1 = 0
foo 'a' 'b' = -1
foo _ _ = -10
This I know won't compile, because it doesn't know whether its args are of type Num or Char. But I can't make its arguments polymorphic, like:
foo :: a -> a -> Int
Because then we are saying it must be a Char (or Int) in the body.
Is it possible to do this in Haskell? I thought of maybe creating a custom type? Something like:
data Bar = Int | Char
foo :: Bar -> Bar -> Int
But I don't think this is valid either. In general, I'm confused about if there's a middle ground between a function in Haskell being either explicitly of ONE type, or polymorphic to a typeclass, prohibiting any usage of a specific type in the function body.
You can do
and things like that - the
Either
data type is precisely for mixing two types together. You can roll your own similar type likeIt's called an Algebraic Data Type.
(I struggle to think of circumstances when it's useful to mix specifically characters and integers together - mainly it's very helpful to know where your data is and what type it is.)
That said, I write algebraic data types a lot, but I give them meaningful names that represent actual things rather than just putting random stuff together because I don't like to be specific. Being very specific or completely general is useful. In between there are typeclasses like
Eq
. You can have a function with typeEq a => a -> [a] -> Bool
which means it has typea -> [a] -> Bool
for any type that has==
defined, and I leave it open for people to use it for data types I never thought of as long as they define an equality function.