Cannot Deduce (simple) Typeclass from context - haskell

I'm getting an error in a pretty simple example and I'm unable to figure out what is wrong. What I'm doing is very similar to mempty in Monoid, here is a simple version (I include my quantified type in case that has something to do with the issue):
data Field a = Field String
| forall b. EsMappable b => ReferenceField String (a -> b)
class EsMappable a where
fields :: [Field a]
toMapping :: (EsMappable a) => a -> String
toMapping a = go "" fields
where go str [] = str
go str (ReferenceField name _ : xs) = go (name ++ str) xs
go str (Field name : xs) =go (name ++ str) xs
The error I get is:
Could not deduce (EsMappable t0) arising from a use of ‘fields’
from the context (EsMappable a)
bound by the type signature for
toMapping :: EsMappable a => a -> String
at search2.hs:11:14-42
The type variable ‘t0’ is ambiguous
In the second argument of ‘go’, namely ‘fields’
In the expression: go "" fields
In an equation for ‘toMapping’:
toMapping a
= go "" fields
where
go str [] = str
go str (ReferenceField name _ : xs) = go (name ++ str) xs
go str (Field name : xs) = go (name ++ str) xs
Note: if I change the EsMapapble class to: fields :: a -> [Field a] and then in toMapping I change go "" (fields a), it works.
My Question: why am I getting this error? Is this not the same as mempty? What is preventing GHC from properly resolving fields?
Thank you!

The problem is that the compiler has no way to link your use of fields to your argument a. Your go function can take in a [Field a] for any a, so you need to somehow specifically constrain it to be the same as the a in your argument type.
You can do this nicely with ScopedTypeVariables:
toMapping :: forall a. (EsMappable a) => a -> String
toMapping _ = go "" (fields :: [Field a])
You need the extra forall a to explicitly make the a type variable scoped. This is a restriction on ScopedTypeVariables in the interest of backwards compatibility.
This would also not have been a problem if you had used your a argument with the Field a values in go. As a contrived example, the following typechecks without the explicit signature:
go str (ReferenceField name f : xs) = go (name ++ str) xs `const` f a
This forces f to take an argument of type a, which constrains the whole list to that specific a. So you could actually use this trick to avoid the ScopedTypeVariables extension if you really wanted to! I wouldn't suggest that though: the extension is about as harmless as they come and makes the code much clearer. This example was just for illustrating my point.

Related

Haskell: "Non type-variable argument in the constraint: Eq Bit" and "No instance for (Eq Bit) arising drom a use of '=='"

data Bit = One
| Zero
deriving Show
type Bits = [Bit]
bits2String :: Bits -> String
bits2String [] = ""
bits2String (x:xs) | x == One = "1" ++ bits2String xs
| x == Zero = "0" ++ bits2String xs
This Code causes following error message:
No instance for (Eq Bit) arising drom a use of '=='
For this error you can find a lot of solutions on SO. They always say you need to add Eq like that:
bits2String :: (Eq Bit) => Bits -> String
bits2String [] = ""
bits2String (x:xs) | x == One = "1" ++ bits2String xs
| x == Zero = "0" ++ bits2String xs
But this doesnt work for me and causes following error
Non type-variable argument in the constraint: Eq Bit
(Use FlexibleContexts to permit this)
{-# LANGUAGE FlexibleContexts #-} doesnt work either.
The original error message is the key one:
No instance for (Eq Bit) arising drom a use of '=='
This arises because you are using the == operator, which is only available for instances of the Eq typeclass - and you haven't given such an instance.
That's easily fixed though. For one you can easily provide the instance manually:
instance Eq Bit where
One == One = True
Zero == Zero = True
_ == _ = False
I wouldn't recommend that you do that though. You can ask Haskell to generate that exact instance for you by simply adding a deriving clause to the type definition. In fact you're already using one, so you can just add Eq to the list of instances you want to derive:
data Bit = One
| Zero
deriving (Show, Eq)
Adding this instance is a good idea in general, because you might well need to compare Bits for equality at some point, especially when working with lists of them - many list functions such as elem depend on Eq instances for their members.
But you can rewrite your bits2String function to not need an Eq instance at all, by pattern matching on the two data constructors:
bits2String :: Bits -> String
bits2String [] = ""
bits2String (One:xs) = "1" ++ bits2String xs
bits2String (Zero:xs) = "0" ++ bits2String xs
In fact, you've basically reimplemented the map function here, so what I would likely do is to define:
bitToChar :: Bit -> Char
bitToChar Zero = '0'
bitToChar One = '1'
(especially as it's the kind of general utility function that you may well want for other things)
and then
bits2String = map bitToChar
None of those require an Eq instance - but it's likely a good idea to derive it anyway, for the reasons I mentioned.
You make use of x == Zero, so of the (==) :: Eq a => a -> a -> Bool function, but you did not make Bit an instance of Eq. You can do so by adding it to the deriving clause, such that Haskell can automatically implement an instance of Eq for your Bit data type:
data Bit = One
| Zero
deriving (Eq, Show)
By default two items are the same if the data constructor is the same, and the parameters (but here your data constructors have no parameters, so it will only check equality of the data constructors).
That being said, you do not need these to be an instance of Eq, you can use pattern matching instead. Indeed:
bits2String :: Bits -> String
bits2String = map f
where f Zero = '0'
f One = '1'
Here we make use of map :: (a -> b) -> [a] -> [b] to convert a list of items to another list by applying a function to each of the items in the original list. Since Bits is a list of Bits, and String is a list of Chars, we can thus map each Bit to a Char to obtain a String of '0's and '1's for the Zero and Ones respectively.

How to restrict a tuple?

I think tuples in Haskell are like
tuple :: (a,b)
which means a and b can be the same type or can be diffrent types
so if i define a function without giving the type for it then i will get probably (t,t1) or some diffrent types when i write :t function in ghci.
So is it possible to get only the same types without defining it in function.
I heard its not allowed in haskell
so i cant write some function like
function [(x,x)]=[(x,x,x)]
to get the
:t function
function :: [(a,a)]->[(a,a,a)]
This is an exercise that i am trying to do and this exercise want me to write a function without defining a type.For example to get
Bool->(Char,Bool)
when i give
:t function
in ghci. i should ve write--
function True=('A',True)
i am not allowed to define the type part of a function
So i cant write
function::(Eq a)=>[(a,a)]->[(a,a,a)]
or something like that
You can use the function asTypeOf from the Prelude to restrict the type of the second component of your tuple to be the same as the type of the first component. For example, in GHCi:
> let f (x, y) = (x, y `asTypeOf` x, x)
> :t f
f :: (t, t) -> (t, t, t)
You can happily restrict the types to be equivalent .. by writing out the required type.
type Pair a = (a,a)
type Triple a = (a,a,a)
and then:
fn :: [Pair a] -> [Triple a]
will enforce the constraint you want.
You can use type, as Don says. Or, if you don't want to bother with that (perhaps you only need it for one function), you can specify the type signature of the function like this:
function :: [(a,a)] -> [(a,a,a)]
function xs = map (\(a, b) -> (a, b, a)) xs -- just an example
I guess what you're looking for is the asTypeOf function. Using it you can restrict a type of some value to be the same as the one of another value in the function definition. E.g.:
Prelude> :t \(a, b) -> (a, b `asTypeOf` a)
\(a, b) -> (a, b `asTypeOf` a) :: (t, t) -> (t, t)
The following should work without asTypeOf:
trans (a,b) = case [a,b] of _ -> (a,b,a)
function xs = map trans xs
OK, if I've understood this correctly, the problem you're having really has nothing to do with types. Your definition,
function [(x,x)]=[(x,x,x)]
won't work because you're saying, in effect, "if the argument to
function is a list with one element, and that element is a tuple,
then call then bind x to the first part of the tuple and also bind
x to the second part of the tuple".
You can't bind a symbol to two expressions at once.
If what you really want is to ensure that both parts of the tuple
are the same, then you can do something like this:
function [(x,y)] = if x == y then [(x,x,x)] else error "mismatch"
or this:
function2 [(x,y)] | x == y = [(x,x,x)]
...but that will fail when the parts of the tuple don't match.
Now I suspect what you really want is to handle lists with more than
one element. So you might want to do something like:
function3 xs = map f xs
where f (x, y) = if x == y then [(x,x,x)] else error "mismatch"
Any of these functions will have the type you want, Eq t => [(t, t)] -> [(t, t, t)] without you having to specify it.

Haskell type declarations

In Haskell, why does this compile:
splice :: String -> String -> String
splice a b = a ++ b
main = print (splice "hi" "ya")
but this does not:
splice :: (String a) => a -> a -> a
splice a b = a ++ b
main = print (splice "hi" "ya")
>> Type constructor `String' used as a class
I would have thought these were the same thing. Is there a way to use the second style, which avoids repeating the type name 3 times?
The => syntax in types is for typeclasses.
When you say f :: (Something a) => a, you aren't saying that a is a Something, you're saying that it is a type "in the group of" Something types.
For example, Num is a typeclass, which includes such types as Int and Float.
Still, there is no type Num, so I can't say
f :: Num -> Num
f x = x + 5
However, I could either say
f :: Int -> Int
f x = x + 5
or
f :: (Num a) => a -> a
f x = x + 5
Actually, it is possible:
Prelude> :set -XTypeFamilies
Prelude> let splice :: (a~String) => a->a->a; splice a b = a++b
Prelude> :t splice
splice :: String -> String -> String
This uses the equational constraint ~. But I'd avoid that, it's not really much shorter than simply writing String -> String -> String, rather harder to understand, and more difficult for the compiler to resolve.
Is there a way to use the second style, which avoids repeating the type name 3 times?
For simplifying type signatures, you may use type synonyms. For example you could write
type S = String
splice :: S -> S -> S
or something like
type BinOp a = a -> a -> a
splice :: BinOp String
however, for something as simple as String -> String -> String, I recommend just typing it out. Type synonyms should be used to make type signatures more readable, not less.
In this particular case, you could also generalize your type signature to
splice :: [a] -> [a] -> [a]
since it doesn't depend on the elements being characters at all.
Well... String is a type, and you were trying to use it as a class.
If you want an example of a polymorphic version of your splice function, try:
import Data.Monoid
splice :: Monoid a=> a -> a -> a
splice = mappend
EDIT: so the syntax here is that Uppercase words appearing left of => are type classes constraining variables that appear to the right of =>. All the Uppercase words to the right are names of types
You might find explanations in this Learn You a Haskell chapter handy.

Get a list of the instances in a type class in Haskell

Is there a way to programmatically get a list of instances of a type class?
It strikes me that the compiler must know this information in order to type check and compile the code, so is there some way to tell the compiler: hey, you know those instances of that class, please put a list of them right here (as strings or whatever some representation of them).
You can generate the instances in scope for a given type class using Template Haskell.
import Language.Haskell.TH
-- get a list of instances
getInstances :: Name -> Q [ClassInstance]
getInstances typ = do
ClassI _ instances <- reify typ
return instances
-- convert the list of instances into an Exp so they can be displayed in GHCi
showInstances :: Name -> Q Exp
showInstances typ = do
ins <- getInstances typ
return . LitE . stringL $ show ins
Running this in GHCi:
*Main> $(showInstances ''Num)
"[ClassInstance {ci_dfun = GHC.Num.$fNumInteger, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Integer.Type.Integer]},ClassInstance {ci_dfun = GHC.Num.$fNumInt, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Int]},ClassInstance {ci_dfun = GHC.Float.$fNumFloat, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Float]},ClassInstance {ci_dfun = GHC.Float.$fNumDouble, ci_tvs = [], ci_cxt = [], ci_cls = GHC.Num.Num, ci_tys = [ConT GHC.Types.Double]}]"
Another useful technique is showing all instances in scope for a given type class using GHCi.
Prelude> :info Num
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
-- Defined in GHC.Num
instance Num Integer -- Defined in GHC.Num
instance Num Int -- Defined in GHC.Num
instance Num Float -- Defined in GHC.Float
instance Num Double -- Defined in GHC.Float
Edit: The important thing to know is that the compiler is only aware of type classes in scope in any given module (or at the ghci prompt, etc.). So if you call the showInstances TH function with no imports, you'll only get instances from the Prelude. If you have other modules in scope, e.g. Data.Word, then you'll see all those instances too.
See the template haskell documentation: http://hackage.haskell.org/packages/archive/template-haskell/2.5.0.0/doc/html/Language-Haskell-TH.html
Using reify, you can get an Info record, which for a class includes its list of instances. You can also use isClassInstance and classInstances directly.
This is going to run into a lot of problems as soon as you get instance declarations like
instance Eq a => Eq [a] where
[] == [] = True
(x:xs) == (y:ys) = x == y && xs == ys
_ == _ = False
and
instance (Eq a,Eq b) => Eq (a,b) where
(a1,b1) == (a2,b2) = a1 == a2 && b1 == b2
along with a single concrete instance (e.g. instance Eq Bool).
You'll get an infinite list of instances for Eq - Bool,[Bool],[[Bool]],[[[Bool]]] and so on, (Bool,Bool), ((Bool,Bool),Bool), (((Bool,Bool),Bool),Bool) etcetera, along with various combinations of these such as ([((Bool,[Bool]),Bool)],Bool) and so forth. It's not clear how to represent these in a String; even a list of TypeRep would require some pretty smart enumeration.
The compiler can (try to) deduce whether a type is an instance of Eq for any given type, but it doesn't read in all the instance declarations in scope and then just starts deducing all possible instances, since that will never finish!
The important question is of course, what do you need this for?
I guess, it's not possible. I explain you the implementation of typeclasses (for GHC), from it, you can see, that the compiler has no need to know which types are instance of a typeclass. It only has to know, whether a specific type is instance or not.
A typeclass will be translated into a datatype. As an example, let's take Eq:
class Eq a where
(==),(/=) :: a -> a -> Bool
The typeclass will be translated into a kind of dictionary, containing all its functions:
data Eq a = Eq {
(==) :: a -> a -> Bool,
(/=) :: a -> a -> Bool
}
Each typeclass constraint is then translated into an extra argument containing the dictionary:
elem :: Eq a => a -> [a] -> Bool
elem _ [] = False
elem a (x:xs) | x == a = True
| otherwise = elem a xs
becomes:
elem :: Eq a -> a -> [a] -> Bool
elem _ _ [] = False
elem eq a (x:xs) | (==) eq x a = True
| otherwise = elem eq a xs
The important thing is, that the dictionary will be passed at runtime. Imagine, your project contains many modules. GHC doesn't have to check all the modules for instances, it just has to look up, whether an instance is defined anywhere.
But if you have the source available, I guess an old-style grep for the instances would be sufficient.
It is not possible to automatically do this for existing classes. For your own class and instances thereof you could do it. You would need to declare everything via Template Haskell (or perhaps the quasi-quoting) and it would automatically generate some strange data structure that encodes the declared instances. Defining the strange data structure and making Template Haskell do this are details left to whomever has a use case for them.
Perhaps you could add some Template Haskell or other magic to your build to include all the source files as text available at run-time (c.f. program quine). Then your program would 'grep itself'...

Why is GHC complaining about wrong type?

This little function checks a (finite) Brainfuck string for validity. It check's whether the [ and ] are balanced. The code is very straightforward and written to be tail-recursive:
-- checks Brainfuck for validity.
validateBrainfuck :: Monad m => String -> m String
validateBrainfuck s = maybe (return s) (fail . fromJust) (validate s 0) where
validate :: String -> Int -> Maybe String -- Here inversed: String means error
validate (']':_ ) 0 = Just "Too many closing brackets"
validate (']':xs) c = validate xs (pred c)
validate ('[':xs) c = validate xs (succ c)
validate ( x :xs) c = validate xs c
validate [] 0 = Nothing
validate [] _ = Just "Too many opening brackets"
Now, GHC complains about typing issues:
Brainfuck.hs:62:58:
Couldn't match expected type `Maybe String'
against inferred type `[Char]'
Expected type: Maybe (Maybe String)
Inferred type: Maybe String
In the third argument of `maybe', namely `(validate s 0)'
In the expression:
maybe (return s) (fail . fromJust) (validate s 0)
Maybe I'm just too silly to figure out what went wrong, but this looks very weird for me.
Look at the type of maybe and think what it should do:
maybe :: b -> (a -> b) -> Maybe a -> b
If the maybe value contains no result (i.e. Nothing), maybe returns the b argument.
Otherwise - when Just a is given - it applies the given function to the valid result. We don't need any fromJust extraction here.
Your code just becomes
maybe (return s) fail (validate s 0)

Resources