If the return of a function is a class ClassA
, is it possible to return in such function any instance of ClassA
? Ex: someFunction :: (ClassA a) => String -> a
So, why this function below does not work? Note that String
is an instance of Eq
getAnyEq :: (Eq a) => String -> a
getAnyEq input |input == "1" = "something"
|otherwise = "other"
The error that occurs is:
Could not deduce (a ~ [Char])
from the context (Eq a)
bound by the type signature for getAnyEq :: Eq a => String -> a
at src/InterceptorRegistry.hs:11:13-33
`a' is a rigid type variable bound by
the type signature for getAnyEq :: Eq a => String -> a
at src/InterceptorRegistry.hs:11:13
I've tried to find this exact explanation on Internet resources but i did not find...could you show me some?
The type Eq a => a
does not mean "A type which implements Eq
", but rather "Any type that implements Eq
. For example, if you implement your function using undefined:
getAnyEq :: (Eq a) => String -> a
getAnyEq str = undefined
The following functions compile correctly (although will crash with a undefined error at runtime):
x,y,z :: Bool
x = getAnyEq "test" == "hello"
y = getAnyEq "test" == [Just (Right True)]
z = getAnyEq "test" == ("this", "sss")
It isn't possible to give a decent implementation of your function, as there is no way of generating the value for the result.
A function that returns a type variable only makes sense when the type variable has an instance of a class which contains a function that returns the value. Eg consider the Num class:
class (Eq a, Show a) => Num a where
(+) :: a -> a -> a
(*) :: a -> a -> a
(-) :: a -> a -> a
negate :: a -> a
abs :: a -> a
signum :: a -> a
fromInteger :: Integer -> a
(note I was testing this on a pretty old version of ghc, your Num may not have Eq or Show constraints).
The function fromInteger
returns an a (without needed an a
as input), so we can get an a
from that type class. The other functions can be used once you have a value. So the following function works:
getANum:: (Num a) => String -> a
getANum "zero" = fromInteger 0
getANum "asdf" = fromInteger 46
getANum _ = fromInteger 1
> getANum "asdf"
46
Note that as a literal integer is effectively parsed as fromInteger <num>
, the fromInteger
function calls in the above function aren't actually necessary. I just included them to show how it works.
Other common type classes which can be used to retrieve a value are:
Monad
(using return
)Applicative
(using pure
)Monoid
(using mempty
)Read
(using read
or any other of its other functions)In addition to @David Miani's wonderful answer, I'd also add that every function type declaration in standard Haskell type system implies a forall
(or ∀) quantifier:
getAnyEq :: (Eq a) => String -> a
is semantically equivalent to
getAnyEq :: forall a . (Eq a) => String -> a
which you can try with the {-# LANGUAGE ExplicitForall #-}
extension. That means, literally, that for each type a
constrained with the type class Eq
there is a function getAnyEq
with the given type. However, you propose the definition for a single type (which is String
) only, not forall
.
I suggest that your definition would be valid with another quantifier, ∃:
getAnyEq :: exists a . (Eq a) => String -> a
It's not implemented by the GHC, but for example the obsolete UHC (Utrecht Haskell Compiler) supports it. Unfortunately, I can't currently try it.
After reading the answers above and the related topic linked on the top of this page, i've concluded that the solution is the using of Existentially Quantified Types.
So, the solution to my getAnyEq
function is:
{-# LANGUAGE ExistentialQuantification #-}
data ShowEq = forall s. Eq s => SE s
getAnyEq :: String -> ShowEq
getAnyEq input |input == "1" = SE "ds"
|otherwise = SE "ss"
A very useful link that explains these types is: http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types
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