Haskell type error: Could not deduce (Show a) arising from a use of `show' from the context (Num a) - haskell

I am configuring xmonad, and since I have to start a couple of dzen instances, I decided that it could be better to use a function that takes the parameters for x and y position, width, height and text align:
-- mydzen.hs
import Data.List
-- | Return a string that launches dzen with the given configuration.
myDzen :: Num a => a -> a -> a -> Char -> String -> String
myDzen y x w ta e =
intercalate " "
[ "dzen2"
, "-x" , show x
, "-w" , show w
, "-y" , show y
, "-h" , myHeight
, "-fn" , quote myFont
, "-bg" , quote myDBGColor
, "-fg" , quote myFFGColor
, "-ta" , [ta]
, "-e" , quote e
]
quote :: String -> String
quote x = "'" x "'"
-- dummy values
myHeigth = "20"
myFont = "bitstream"
myDBGColor = "#ffffff"
myFFGColor = "#000000"
Could not deduce (Show a) arising from a use of `show'
from the context (Num a)
bound by the type signature for
myDzen :: Num a => a -> a -> a -> Char -> String -> String
at mydzen.hs:(5,1)-(17,13)
Possible fix:
add (Show a) to the context of
the type signature for
myDzen :: Num a => a -> a -> a -> Char -> String -> String
In the expression: show x
In the second argument of `intercalate', namely
`["dzen2", "-x", show x, "-w", ....]'
In the expression:
intercalate " " ["dzen2", "-x", show x, "-w", ....]
Obviously, deleting the signature, or changing Num a for Show a solves the issue, but I can't understand why. The 'arguments' x, w and y are supposed to be almost any kind of numbers (100, 550.2, 1366 * 0.7 ecc).
I'm new to haskell and until now I haven't been able to (clearly) understand the error or find what's wrong.

Previously, Show and Eq were superclasses of Num and the code would compile.
In the new GHC, from version 7.4, this has changed, now Num does not depend on Show and Eq, so you need to add them to signatures.
The reason is separation of concerns - there are numeric types with no sensible equality and show function (computable reals, rings of functions).

Not all numbers are showable (standard types like Int or Integer are, but you could have defined your own type; how would compiler know?) You’re using show x in your function — therefore, a must belong to Show typeclass. You can change your signature to myDzen :: (Num a, Show a) => a -> a -> a -> Char -> String -> String and get rid of the error.

show is not part of the Num type class — to be able to use it, you have to add Show constraint alongside the Num one:
myDzen :: (Num a, Show a) => a -> a -> a -> Char -> String -> String

Related

Basic Haskell function types?

Super basic question - but I can't seem to get a clear answer. The below function won't compile:
randomfunc :: a -> a -> b
randomfunc e1 e2
| e1 > 2 && e2 > 2 = "Both greater"
| otherwise = "Not both greater"
main = do
let x = randomfunc 2 1
putStrLn $ show x
I'm confused as to why this won't work. Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
Error:
"Couldn't match expected type ‘b’ with actual type ‘[Char]’"
Not quite. Your function signature indicates: for all types a and b, randomfunc will return something of type b if given two things of type a.
However, randomFunc returns a String ([Char]). And since you compare e1 with 2 each other, you cannot use all a's, only those that can be used with >:
(>) :: Ord a => a -> a -> Bool
Note that e1 > 2 also needs a way to create such an an a from 2:
(> 2) :: (Num a, Ord a) => a -> Bool
So either use a specific type, or make sure that you handle all those constraints correctly:
randomfunc :: Int -> Int -> String
randomFunc :: (Ord a, Num a) => a -> a -> String
Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
In a Haskell type signature, when you write names that begin with a lowercase letter such as a, the compiler implicitly adds forall a. to the beginning of the type. So, this is what the compiler actually sees:
randomfunc :: forall a b. a -> a -> b
The type signature claims that your function will work for whatever ("for all") types a and b the caller throws at you. But this is not true for your function, since it only works on Int and String respectively.
You need to make your type more specific:
randomfunc :: Int -> Int -> String
On the other hand, perhaps you intended to ask the compiler to fill out a and b for you automatically, rather than to claim that it will work for all a and b. In that case, what you are really looking for is the PartialTypeSignatures feature:
{-# LANGUAGE PartialTypeSignatures #-}
randomfunc :: _a -> _a -> _b

What exactly does => do in haskell? [duplicate]

This question already has answers here:
What does => mean in a type signature?
(3 answers)
Closed 7 years ago.
I've just started reading through Learn You a Haskell for Great Good. In chapter 3, I've seen the author use => but I could not find out exactly what it does and why they use it.
I think this is the first time it was used:
lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"
lucky x = "Sorry, you're out of luck, pal!"
Here is another example:
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
Thanks.
In short:
Although not complete, if you haven't yet read about classes, you can see it as a constraint that there is defined a set of functions on the type a.
Explanation:
You can see it as putting constraints on a type. For instance in the case of lucky:
lucky :: (Integral a) => a -> String
It means the function is defined for any type a, as long as a is an instance of Integral.
Now I don't know if you are familiar with classes yet (those are not the ones used in object-oriented programming), but classes more or less introduce functions on a that can then by used in your function definition. For instance the class Integral is defined as:
class (Real a, Enum a) => Integral a where
quot :: a -> a -> a
rem :: a -> a -> a
div :: a -> a -> a
mod :: a -> a -> a
quotRem :: a -> a -> (a, a)
divMod :: a -> a -> (a, a)
toInteger :: a -> Integer
Now this class is rather hard to understand since it uses => in the signature as well. Perhaps an easier one is Show:
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
It means that if a is an instance of Show, that you can use the show function on a. Otherwise the following line:
tell (x:[]) = "The list has one element: " ++ show x
would not compile since Haskell isn't sure it can call show on x. By constraining the type a however, we know that we can only use tell on types where a is an instance of Show, and thus the show function is defined.
It constrains a parameter a to a certain class, in this case Integral and Show

Defaulting the following constraints to type 'Double' when using Scientific

I have two scientific numbers that are necessarily Integers that I want to convert to Ints, as below.
Please ignore code conventions and the idiomaticness of the code.
> import qualified Data.Vector as V
> import Data.Scientific
> cToTy (Array v) = case V.toList v of
> [String nm, Number p, Number s]
> | all (==True) $ map isInteger [p,s] -- We make sure they're always integers
> , [pr,sc] <- map (forceEitherToInt . floatingOrInteger) [p,s] -- And then hack them out
> forceEitherToInt :: (RealFloat r, Integral i) => Either r i -> Int
> forceEitherToInt (Left _a) = 0 -- This shouldn't happen, so we'll default it to 0 all the time.
> forceEitherToInt (Right a) = fromIntegral a
However, I get this warning and I can't figure out how to rid myself of them.
JsonUtils.lhs:76:26: Warning:
Defaulting the following constraint(s) to type ‘Double’
(RealFloat r0) arising from a use of ‘forceEitherToInt’
In the first argument of ‘(.)’, namely ‘forceEitherToInt’
In the first argument of ‘map’, namely
‘(forceEitherToInt . floatingOrInteger)’
In a stmt of a pattern guard for
a case alternative:
[pr, sc] <- map (forceEitherToInt . floatingOrInteger) [p, s]
Does anyone have any thoughts or ideas?
First off, you can explicitly cause an error if "neither should happen"; second, you can drop RealFloat as #bheklilr states; thirdly you can specify the double more concretely if you prefer the double; fourthly it can help with Hungarian notation if you write 'A from B' rather than 'B to A' in your names. So you could write for example:
intFromEither :: (Integral i) => Either Double i -> Int
intFromEither (Left d) = error $
"intFromEither tried to coerce `Left " ++ show d ++ "` to an Int."
intFromEither (Right i) = fromIntegral i
You can replace the Double above with x to make it more general; the most general type signature here is (Integral a, Num b) => Either t a -> b.

how do I get my literal to be a num in haskell

So I'm quite the newb in haskell and questions abound. I've been reading through a couple books and trying to do a few things on my own, can someone please explain to me why this is complaining that the literal doesn't implement eq, I understand why eq is necessary- but I don't understand why this is seen as a literal rather than a num or how I change that.
generateListOfRandoms :: a -> b -> c -> d -> [(d, (a, b))]
generateListOfRandoms _ _ 0 _ = []
generateListOfRandoms rangeStart rangeEnd numberOfRandoms randGenerator =
(randGenerator, (rangeStart,rangeEnd)) : generateListOfRandoms rangeStart rangeEnd (numberOfRandoms-1) randGenerator
I'm sure my function is going to fail in other ways when I try giving it an IO function as some of you could guess, but I'm confused right now why I get this error:
src\Main.hs:23:27:
No instance for (Eq c)
arising from the literal `0'
In the pattern: 0
In an equation for `generateListOfRandoms':
generateListOfRandoms _ _ 0 _ = []
If you use a numeric literal, the type of the corresponding argument must belong to the Num class. Also, since you are pattern-matching against a numeric literal, you need the type to belong to the Eq class. You have to add these constraints to your type signature,
generateListOfRandoms :: (Num c, Eq c) => a -> b -> c -> d -> [(d, (a, b))]
If you're not using GHC-7.4, the Eq constraint is implied by the Num constraint, that has recently been changed, so now you have to state both explicitly if you use both.

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.

Resources