How to tell whether variable is a certain data in Haskell? - haskell

Edit: This class instance of QWhere fails when it's passed input like this: >qWhere fly john even though fly is type Argument -> Argument -> Predicate and john is type Argument.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
data Argument = Argument { ttype :: Type, value :: String } deriving (Show, Eq)
data Predicate = Predicate { lemma :: String, arguments :: [Argument] } deriving (Show, Eq)
class Fly a b where
fly :: a -> b -> Predicate
instance Fly Argument Argument where
fly x y = Predicate { lemma = "fly", arguments = [x, y] }
instance Fly Argument Predicate where
fly x y = Predicate { lemma = "fly", arguments = [x, arguments y !! 0] }
class QWhere a b where
qWhere :: a -> b -> String
instance QWhere (Argument -> Argument -> Predicate) Argument where
qWhere x y = "hi"
This is the output from the ghci:
No instance for (QWhere (a0 -> b0 -> Predicate) Argument)
arising from a use of ‘qWhere’
The type variables ‘a0’, ‘b0’ are ambiguous
Note: there is a potential instance available:
instance QWhere (Argument -> Argument -> Predicate) Argument
-- Defined at new_context.hs:116:10
In the expression: qWhere fly john
In an equation for ‘it’: it = qWhere fly john
No instance for (Fly a0 b0) arising from a use of ‘fly’
The type variables ‘a0’, ‘b0’ are ambiguous
Note: there are several potential instances:
instance Fly Argument Predicate
-- Defined at new_context.hs:110:10
instance Fly Argument Argument
-- Defined at new_context.hs:107:10
In the first argument of ‘qWhere’, namely ‘fly’
In the expression: qWhere fly john
In an equation for ‘it’: it = qWhere fly john
These questions are relevant, but none of the answers have solved my problem.
(1) Checking for a particular data constructor
(2) Test if Haskell variable matches user-defined data type option
And some internet sources which should address this question but I could not find the solution from:
(3) https://www.haskell.org/haskellwiki/Determining_the_type_of_an_expression
(4) http://okmij.org/ftp/Haskell/typeEQ.html
My problem: I have two Haskell data types defined. I am given an input and I need to determine if it belongs to data type A or data type B.
Here is the data types definition:
data Argument = Argument { ttype :: Type, value :: String } deriving (Show, Eq)
data Predicate = Predicate { lemma :: String, arguments :: [Argument] } deriving (Show, Eq)
I need a function which returns true/false if a variable is a data type Argument or Predicate.
I attempted to follow the answers of both SO questions, but only got complaints from the ghci compiler:
--checks if a variable is of data type Argument
--this does not compile (from question (2))
isArgument :: a -> Bool
isArgument (Argument _) = True
isArgument _ = False
--from question (1), also fails
isArgument :: a -> String
isArgument value =
case token of
Argument arg -> "is argument"
Predicate p -> "is predicate"

The sort of dynamic typing you are trying to do is very rarely used in Haskell. If you want to write functions that can take values of both Predicate and Argument there are at least two idiomatic ways depending on your exact use-case.
The first is to overload the function using type-classes. E.g.
class IsArgument a where
isArgument :: a -> Bool
instance IsArgument Argument where
isArgument _ = True
instance IsArgument Predicate where
isArgument _ = False
The second is to use some sum-type such as Either Predicate Argument or a custom sum-type such as:
data Expr = ArgumentExpr Argument | PredicateExpr Predicate
isArgument :: Expr -> Bool
isArgument (ArgumentExpr _) = True
isArgument _ = False
You can also make Argument and Predicate constructors of the same type, but then of course you lose the type safety of treating them as separate types. You can circumvent this by using a GADT and tagging the constructors with a phantom type but this gets into the slightly more advanced type extensions that GHC offers:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
data ExprType = Argument | Predicate
data Expr t where
ArgumentExpr :: { ttype :: Type, value :: String } -> Expr Argument
PredicateExpr :: { lemma :: String, arguments :: [Expr Argument] } -> Expr Predicate
deriving instance Show (Expr t)
deriving instance Eq (Expr t)
isArgument :: Expr t -> Bool
isArgument (ArgumentExpr {}) = True
isArgument _ = False
Now arguments and predicates are constructors of the same type but you can limit the values to a specific constructor by using the type parameter as is done in arguments :: [Expr Argument] but you can also just accept any expression using the type Expr t as in isArgument.
If you really really need run-time polymorphism, it can be achieved using the Typeable type-class which enables you to get runtime type information and do type-casts on opaque, generic types.
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Argument = Argument { ttype :: Type, value :: String } deriving (Show, Eq, Typeable)
data Predicate = Predicate { lemma :: String, arguments :: [Argument] } deriving (Show, Eq, Typeable)
isArgument :: Typeable a => a -> Bool
isArgument a = case cast a of
Just (Argument {}) -> True
_ -> False
The function cast tries to convert any Typeable a => a value into some known type and returns a Just value if the type-cast succeeds and Nothing if it fails.

You can do what you want by making Argument and Predicate part of the same type....
data LogicElement = Argument { ttype :: Type, value :: String } |
Predicate { lemma :: String, arguments :: [LogicElement] } deriving (Show, Eq)
While it is possible to define a function of type (a->Bool), it is unusual, and generally implies that the value being input will be ignored (ie- how can you do anything to something if you don't even know what it is? You pretty much can only apply other (a->b) functions on it).
In the particular example, you compiler will complain at the following
isArgument (Argument _) = True
because the pattern implicitly implies that the input argument must be type Argument, whereas the signature you gave was undefined type a.

When you say that isArgument has type a -> Bool, you're saying that it can take any, or rather every possible a, not just certain ones. There are a few solutions to this, though. My preference would be that for simple alternatives, just use Either:
import Data.Either
isArgument :: Either Argument Predicate -> Bool
isArgument = isLeft
Or
-- Note the use of {} instead of _, the {} expands to all fields in a record
-- the _ only would have taken the place of the ttype field, although you could have
-- (Argument _ _) to capture both fields of the Argument constructor
isArgument :: Either Argument Predicate -> Bool
isArgument (Left (Argument {})) = True
isArgument _ = False
Although, the only use of this sort of function would be when you aren't sure which data type you have, and a value in Haskell can't be ambiguously typed. It would be equivalent to if you had in Java/C/C++/C# something like
if (some_condition) {
x = "a string";
} else {
x = 5;
}
These are statically typed languages, a variable can't take on values of two different types. The same holds in Haskell. If you wanted to give a type to a variable that could take on two different values, you'd have to write a container for it. The Either container in Haskell is pre-defined for this purpose.

Related

Why can't I match type Int with type a

Haskell Noob here.
An oversimplified case of what I'm trying to do here:
test :: Int -> a
test i = i -- Couldn't match expected type ‘a’ with actual type ‘Int’. ‘a’ is a rigid type variable bound by ...
I don't quite understand why this wouldn't work. I mean, Int is surely included in something of type a.
What I was really trying to achieve is this:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
data EnumType = Enum1 | Enum2 | Enum3
data MyType (a :: EnumType) where
Type1 :: Int -> MyType 'Enum1
Type2 :: String -> MyType 'Enum2
Type3 :: Bool -> MyType 'Enum3
myFunc :: EnumType -> MyType 'Enum1 -> MyType any
myFunc Enum1 t = t -- Can't match type `any` with `Enum1`. any is a rigid type variable bound by ...
myFunc Enum2 _ = Type2 "hi"
myFunc Enum3 _ = Type3 True
What is going on here? Is there a way to work around this or is it just something you can't do?
For the GADT function you want to write, the standard technique is to use singletons. The problem is that values of type EnumType are value-level things, but you want to inform the type system of something. So you need a way to connect types of kind EnumType with values of type EnumType (which itself has kind Type). That's impossible, so we cheat: we connect types x of kind EnumType with values of a new type, SEnumType x, such that the value uniquely determines x. Here's how it looks:
data SEnumType a where
SEnum1 :: SEnumType Enum1
SEnum2 :: SEnumType Enum2
SEnum3 :: SEnumType Enum3
myFunc :: SEnumType a -> MyType Enum1 -> MyType a
myFunc SEnum1 t = t
myFunc SEnum2 _ = Type2 "hi"
myFunc SEnum3 _ = Type3 True
Now the a in the return type MyType a isn't just fabricated out of thin air; it is constrained to be equal to the incoming a from SEnumType, and pattern matching on which SEnumType it is lets you observe whether a is Enum1, Enum2, or Enum3.
Is there a way to work around this or is it just something you can't do?
I'm afraid that it's just "something you can't do". The reason is simple to explain.
When you write a type signature like (to take your first, simpler example)
test :: Int -> a
or, to write it the more literal, expanded form
test :: forall a. Int -> a
You are saying that literally, "for all a", this function can take an Int and return a value of type a. This is important, because calling code has to believe this type signature and therefore be able to do something like this (this isn't realistic code, but imagine a case where you feed the result of test 2 to a function that requires a Char or one of those other types):
test 2 :: Char
test 2 :: [Int]
test 2 :: (Double, [Char])
and so on. Clearly your function can't work with any of these examples - but it has to be able to work with any of them if you give it this type signature. Your code, quite simply, does not fit that type signature. (And nor could any, unless you "cheat" by having eg test x = undefined.)
This shouldn't be a problem though - the compiler is simply protecting you from a mistake, because I'm sure you realise that your code cannot satisfy this type signature. To take your "real" example:
myFunc :: EnumType -> MyType Enum1 -> MyType any
although this produces a compilation error, your code in the function is likely correct, and the problem is the type signature. If you replace it with
myFunc :: EnumType -> MyType Enum1 -> MyType Enum1
then it will compile (barring any further errors, which I've not checked it for), and presumably do what you want. It doesn't look like you actually want to be able to call myFunc and have it produce, say, a MyType Int. (If by any chance you do, I'd suggest you ask a separate question where you elaborate on what you actually need here.)
As was already said, your signature expresses a universal type
myFunc :: ∀ a . EnumType -> MyType 'Enum1 -> MyType a
whereas what you're actually trying to express is an existential type
myFunc :: EnumType -> MyType 'Enum1 -> (∃ a . MyType a)
Haskell doesn't have a feature quite like that, but it does have some way to achieve essentially the same thing.
Both GADTs and the ExistentialTypes extension allow expressing existentials, but you need to define a separate type for them.
data MyDynType where
MyDynWrap :: MyType a -> MyDynType
myFunc :: EnumType -> MyType 'Enum1 -> MyDynType
myFunc Enum1 t = MyDynWrap t
myFunc Enum2 _ = MyDynWrap $ Type2 "hi"
myFunc Enum3 _ = MyDynWrap $ Type3 True
Maybe you don't even need a separate type, but can simply modify MyType to be “dynamic” in the first place.
data MyType = Type1 Int | Type2 String | Type3 Bool
myFunc :: EnumType -> MyType -> MyType
myFunc Enum1 (Type1 i) = Type1 i
myFunc Enum2 _ = Type2 "hi"
myFunc Enum3 _ = Type3 True
existentials can be emulated at the spot, anonymously, by unwrapping a layer of continuation-passing style and then using the dual universal quantifier via the RankNTypes extension.
{-# LANGUAGE RankNTypes #-}
data MyType (a :: EnumType) where ... -- as original
myFunc :: EnumType -> MyType 'Enum1 -> (∀ a . MyType a -> r) -> r
myFunc Enum1 t q = q t
myFunc Enum2 _ q = q (Type2 "hi")
myFunc Enum3 _ q = q (Type3 True)
the GADT function you want to write, the standard technique is to use singletons. The problem is that values of type EnumType are ...

Deriving Eq and Show for an ADT that contains fields that can't have Eq or Show

I'd like to be able to derive Eq and Show for an ADT that contains multiple fields. One of them is a function field. When doing Show, I'd like it to display something bogus, like e.g. "<function>"; when doing Eq, I'd like it to ignore that field. How can I best do this without hand-writing a full instance for Show and Eq?
I don't want to wrap the function field inside a newtype and write my own Eq and Show for that - it would be too bothersome to use like that.
One way you can get proper Eq and Show instances is to, instead of hard-coding that function field, make it a type parameter and provide a function that just “erases” that field. I.e., if you have
data Foo = Foo
{ fooI :: Int
, fooF :: Int -> Int }
you change it to
data Foo' f = Foo
{ _fooI :: Int
, _fooF :: f }
deriving (Eq, Show)
type Foo = Foo' (Int -> Int)
eraseFn :: Foo -> Foo' ()
eraseFn foo = foo{ fooF = () }
Then, Foo will still not be Eq- or Showable (which after all it shouldn't be), but to make a Foo value showable you can just wrap it in eraseFn.
Typically what I do in this circumstance is exactly what you say you don’t want to do, namely, wrap the function in a newtype and provide a Show for that:
data T1
{ f :: X -> Y
, xs :: [String]
, ys :: [Bool]
}
data T2
{ f :: OpaqueFunction X Y
, xs :: [String]
, ys :: [Bool]
}
deriving (Show)
newtype OpaqueFunction a b = OpaqueFunction (a -> b)
instance Show (OpaqueFunction a b) where
show = const "<function>"
If you don’t want to do that, you can instead make the function a type parameter, and substitute it out when Showing the type:
data T3' a
{ f :: a
, xs :: [String]
, ys :: [Bool]
}
deriving (Functor, Show)
newtype T3 = T3 (T3' (X -> Y))
data Opaque = Opaque
instance Show Opaque where
show = const "..."
instance Show T3 where
show (T3 t) = show (Opaque <$ t)
Or I’ll refactor my data type to derive Show only for the parts I want to be Showable by default, and override the other parts:
data T4 = T4
{ f :: X -> Y
, xys :: T4' -- Move the other fields into another type.
}
instance Show T4 where
show (T4 f xys) = "T4 <function> " <> show xys
data T4' = T4'
{ xs :: [String]
, ys :: [Bool]
}
deriving (Show) -- Derive ‘Show’ for the showable fields.
Or if my type is small, I’ll use a newtype instead of data, and derive Show via something like OpaqueFunction:
{-# LANGUAGE DerivingVia #-}
newtype T5 = T5 (X -> Y, [String], [Bool])
deriving (Show) via (OpaqueFunction X Y, [String], [Bool])
You can use the iso-deriving package to do this for data types using lenses if you care about keeping the field names / record accessors.
As for Eq (or Ord), it’s not a good idea to have an instance that equates values that can be observably distinguished in some way, since some code will treat them as identical and other code will not, and now you’re forced to care about stability: in some circumstance where I have a == b, should I pick a or b? This is why substitutability is a law for Eq: forall x y f. (x == y) ==> (f x == f y) if f is a “public” function that upholds the invariants of the type of x and y (although floating-point also violates this). A better choice is something like T4 above, having equality only for the parts of a type that can satisfy the laws, or explicitly using comparison modulo some function at use sites, e.g., comparing someField.
The module Text.Show.Functions in base provides a show instance for functions that displays <function>. To use it, just:
import Text.Show.Functions
It just defines an instance something like:
instance Show (a -> b) where
show _ = "<function>"
Similarly, you can define your own Eq instance:
import Text.Show.Functions
instance Eq (a -> b) where
-- all functions are equal...
-- ...though some are more equal than others
_ == _ = True
data Foo = Foo Int Double (Int -> Int) deriving (Show, Eq)
main = do
print $ Foo 1 2.0 (+1)
print $ Foo 1 2.0 (+1) == Foo 1 2.0 (+2) -- is True
This will be an orphan instance, so you'll get a warning with -Wall.
Obviously, these instances will apply to all functions. You can write instances for a more specialized function type (e.g., only for Int -> String, if that's the type of the function field in your data type), but there is no way to simultaneously (1) use the built-in Eq and Show deriving mechanisms to derive instances for your datatype, (2) not introduce a newtype wrapper for the function field (or some other type polymorphism as mentioned in the other answers), and (3) only have the function instances apply to the function field of your data type and not other function values of the same type.
If you really want to limit applicability of the custom function instances without a newtype wrapper, you'd probably need to build your own generics-based solution, which wouldn't make much sense unless you wanted to do this for a lot of data types. If you go this route, then the Generics.Deriving.Show and Generics.Deriving.Eq modules in generic-deriving provide templates for these instances which could be modified to treat functions specially, allowing you to derive per-datatype instances using some stub instances something like:
instance Show Foo where showsPrec = myGenericShowsPrec
instance Eq Foo where (==) = myGenericEquality
I proposed an idea for adding annotations to fields via fields, that allows operating on behaviour of individual fields.
data A = A
{ a :: Int
, b :: Int
, c :: Int -> Int via Ignore (Int->Int)
}
deriving
stock GHC.Generic
deriving (Eq, Show)
via Generically A -- assuming Eq (Generically A)
-- Show (Generically A)
But this is already possible with the "microsurgery" library, but you might have to write some boilerplate to get it going. Another solution is to write separate behaviour in "sums-of-products style"
data A = A Int Int (Int->Int)
deriving
stock GHC.Generic
deriving
anyclass SOP.Generic
deriving (Eq, Show)
via A <-𝈖-> '[ '[ Int, Int, Ignore (Int->Int) ] ]

Associated type family complains about `pred :: T a -> Bool` with "NB: ‘T’ is a type function, and may not be injective"

This code:
{-# LANGUAGE TypeFamilies #-}
module Study where
class C a where
type T a :: *
pred :: T a -> Bool
— Gives this error:
.../Study.hs:7:5: error:
• Couldn't match type ‘T a’ with ‘T a0’
Expected type: T a -> Bool
Actual type: T a0 -> Bool
NB: ‘T’ is a type function, and may not be injective
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘Study.pred’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
When checking the class method:
Study.pred :: forall a. A a => T a -> Bool
In the class declaration for ‘A’
|
7 | pred :: T a -> Bool
| ^^^^^^^^^^^^^^^^^^^
Replacing type keyword with data fixes.
Why is one wrong and the other correct?
What do they mean by "may not be injective"? What kind of function that is if it is not even allowed to be one to one? And how is this related to the type of pred?
instance C Int where
type T Int = ()
pred () = False
instance C Char where
type T Char = ()
pred () = True
So now you have two definitions of pred. Because a type family assigns just, well, type synonyms, these two definitions have the signatures
pred :: () -> Bool
and
pred :: () -> Bool
Hm, looks rather similar, doesn't it? The type checker has no way to tell them apart. What, then, is
pred ()
supposed to be? True or False?
To resolve this, you need some explicit way of providing the information of which instance the particular pred in some use case is supposed to belong to. One way to do that, as you've discovered yourself, is to change to an associated data family: data T Int = TInt and data T Char = TChar would be two distinguishable new types, rather than synonyms to types, which have no way to ensure they're actually different. I.e. data families are always injective; type families sometimes aren't. The compiler assumes, in the absence of other hints, that no type family is injective.
You can declare a type family injective with another language extension:
{-# LANGUAGE TypeFamilyDependencies #-}
class C a where
type T a = (r :: *) | r -> a
pred :: T a -> a
The = simply binds the result of T to a name so it is in scope for the injectivity annotation, r -> a, which reads like a functional dependency: the result of T is enough to determine the argument. The above instances are now illegal; type T Int = () and type T Char = () together violate injectivity. Just one by itself is admissible.
Alternatively, you can follow the compiler's hint; -XAllowAmbiguousTypes makes the original code compile. However, you will then need -XTypeApplications to resolve the instance at the use site:
pred #Int () == False
pred #Char () == True

How can I read the metadata of a type at runtime?

I'd like to write a program that prints out some metadata of a Haskell type. Although I know this isn't valid code, the idea is something like:
data Person = Person { name :: String, age :: Int }
metadata :: Type -> String
metadata t = ???
metadata Person -- returns "Person (name,age)"
The important restriction being I don't have an instance of Person, just the type.
I've started looking into Generics & Typeable/Data, but without an instance I'm not sure they'll do what I need. Can anyone point me in the right direction?
Reflection in Haskell works using the Typeable class, which is defined in Data.Typeable and includes the typeOf* method to get a run-time representation of a value's type.
ghci> :m +Data.Typeable
ghci> :t typeOf 'a'
typeOf 'a' :: TypeRep
ghci> typeOf 'a' -- We could use any value of type Char and get the same result
Char -- the `Show` instance of `TypeRep` just returns the name of the type
If you want Typeable to work for your own types, you can have the compiler generate an instance for you with the DeriveDataTypeable extension.
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Person = Person { name :: String, age :: Int } deriving Typeable
You can also write your own instance, but really, no one has the time for that. Apparently you can't - see the comments
You can now use typeOf to grab a run-time representation of your type. We can query information about the type constructor (abbreviated to TyCon) and its type arguments:
-- (undefined :: Person) stands for "some value of type Person".
-- If you have a real Person you can use that too.
-- typeOf does not use the value, only the type
-- (which is known at compile-time; typeOf is dispatched using the normal instance selection rules)
ghci> typeOf (undefined :: Person)
Person
ghci> tyConName $ typeRepTyCon $ typeOf (undefined :: Person)
"Person"
ghci> tyConModule $ typeRepTyCon $ typeOf (undefined :: Person)
"Main"
Data.Typeable also provides a type-safe cast operation which allows you to branch on a value's runtime type, somewhat like C#'s as operator.
f :: Typeable a => a -> String
f x = case (cast x :: Maybe Int) of
Just i -> "I can treat i as an int in this branch " ++ show (i * i)
Nothing -> case (cast x :: Maybe Bool) of
Just b -> "I can treat b as a bool in this branch " ++ if b then "yes" else "no"
Nothing -> "x was of some type other than Int or Bool"
ghci> f True
"I can treat b as a bool in this branch yes"
ghci> f (3 :: Int)
"I can treat i as an int in this branch 9"
Incidentally, a nicer way to write f is to use a GADT enumerating the set of types you expect your function to be called with. This allows us to lose the Maybe (f can never fail!), does a better job of documenting our assumptions, and gives compile-time feedback when we need to change the set of admissible argument types for f. (You can write a class to make Admissible implicit if you like.)
data Admissible a where
AdInt :: Admissible Int
AdBool :: Admissible Bool
f :: Admissible a -> a -> String
f AdInt i = "I can treat i as an int in this branch " ++ show (i * i)
f AdBool b = "I can treat b as a bool in this branch " ++ if b then "yes" else "no"
In reality I probably wouldn't do either of these - I'd just stick f in a class and define instances for Int and Bool.
If you want run-time information about the right-hand side of a type definition, you need to use the entertainingly-named Data.Data, which defines a subclass of Typeable called Data.** GHC can derive Data for you too, with the same extension:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
import Data.Data
data Person = Person { name :: String, age :: Int } deriving (Typeable, Data)
Now we can grab a run-time representation of the values of a type, not just the type itself:
ghci> dataTypeOf (undefined :: Person)
DataType {tycon = "Main.Person", datarep = AlgRep [Person]}
ghci> dataTypeConstrs $ dataTypeOf (undefined :: Person)
[Person] -- Person only defines one constructor, called Person
ghci> constrFields $ head $ dataTypeConstrs $ dataTypeOf (undefined :: Person)
["name","age"]
Data.Data is the API for generic programming; if you ever hear people talking about "Scrap Your Boilerplate", this (along with Data.Generics, which builds on Data.Data) is what they mean. For example, you can write a function which converts record types to JSON using reflection on the type's fields.
toJSON :: Data a => a -> String
-- Implementation omitted because it is boring.
-- But you only have to write the boring code once,
-- and it'll be able to serialise any instance of `Data`.
-- It's a good exercise to try to write this function yourself!
* In recent versions of GHC, this API has changed somewhat. Consult the docs.
** Yes, the fully-qualified name of that class is Data.Data.Data.

Returning an instance of a class in a Haskell Function [duplicate]

This question already has answers here:
Return specific type within Haskell
(3 answers)
Closed 8 years ago.
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

Resources