Ambigous type variable that prevents the constraint - haskell

I am fiddling around with IO and i do not understand the following error :
* Ambiguous type variable `a0' arising from a use of `readLine'
prevents the constraint `(Console a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instance exist:
instance Console Int -- Defined at Tclass.hs:8:14
* In the second argument of `(+)', namely `readLine'
In the second argument of `($)', namely `(2 + readLine)'
In the expression: putStrLn . show $ (2 + readLine)
|
17 | useInt =putStrLn . show $ (2+readLine)
Code
module Tclass where
import System.Environment
class Console a where
writeLine::a->IO()
readLine::IO a
instance Console Int where
writeLine= putStrLn . show
readLine = do
a <- getLine
let b= (read a)::Int
return b
useInt::IO()
useInt =putStrLn . show $ (2+readLine)
P.S i do not understand shouldn't the compiler infer the type of the instance for readLine and make the addition with 2 in the useInt method ?

2 is not only an Int in Haskell but it is of any numeric type, including Float,Double,Integer,.... Its type is Num a => a -- a polymorphic type fitting each numeric type.
So, you could use (2::Int) instead. Then you'll discover that (2::Int) + readLine is a type error, since readLine :: Int is wrong, we only get readLine :: IO Int.
You can try this, instead
useInt :: IO ()
useInt = do
i <- readLine
putStrLn . show (2 + i :: Int)

Related

Haskell warning

I have written the code (I'm new to haskell, very new) and can't solve the warning.
problem:
funk :: Num a => a -> a
funk a = a + 10
main :: IO()
main = print (funk 10 )
Warning:
Warnings: 1
/home/anmnv/Desktop/qqq.hs: line 4, column 8:
Warning: • Defaulting the following constraints to type ‘Integer’
(Show a0) arising from a use of ‘print’ at qqq.hs:4:8-23
(Num a0) arising from a use of ‘funk’ at qqq.hs:4:15-21
• In the expression: print (funk 10)
In an equation for ‘main’: main = print (funk 10)
It simply says that you did not specify the type for 10. It can strictly speaking by any type that is an member of the Num typeclass, but the compiler uses defaulting rules, and thus picks an Integer.
You can give Haskell a type constraint to determine the type of 10, for example:
funk :: Num a => a -> a
funk = (+ 10)
main :: IO ()
main = print (funk (10 :: Integer))

Haskell Wreq - Couldn't match expected type ‘GHC.Exts.Item a0’

I'm experiencing a type error when I run the following code:
runPost :: IO String
runPost = do
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
return $ show res
The error is the following:
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘FormParam’
The type variable ‘a0’ is ambiguous
• In the expression: "num" := (31337 :: Int)
In the second argument of ‘post’, namely
‘["num" := (31337 :: Int)]’
In a stmt of a 'do' block:
res <- post "http://httpbin.org/post" ["num" := (31337 :: Int)]
When I inspect the type of := in ghci, I see what appears to be the correct type:
*Main Network.Wreq> :t (:=)
(:=)
:: FormValue v =>
Data.ByteString.Internal.ByteString -> v -> FormParam
What I'm wondering is why GHC.Exts.Item is appearing as the expect type when I run the compiler. I've only imported the functions I'm using from Network.Wreq. Any ideas what might be going on here?
It's clear (to the compiler, if not to your fellow human) that ("num" := (31337 :: Int)) :: FormParam. What isn't clear to the compiler (and which you need to help it decide on) is the type of [x] once x is known to be a FormParam.
The Item "type" is actually a type family, coming from the IsList class; and the IsList connection is coming from having the OverloadedLists extension turned on.
Here's a minimal program that causes basically the same error, which should make it more clear what's going on:
{-# LANGUAGE OverloadedLists #-}
main :: IO ()
main = print [True]
• Couldn't match expected type ‘GHC.Exts.Item a0’
with actual type ‘Bool’
The type variable ‘a0’ is ambiguous
• In the expression: True
In the first argument of ‘print’, namely ‘[True]’
In the expression: print [True]
|
4 | main = print [True]
| ^^^^
The print function has type Show a => a -> IO (). If the OverloadedLists extension weren't enabled, then the expression [True] would have type [Bool], and everything would be fine. But with the OverloadedLists extension enabled, the expression [True] instead has type (GHC.Exts.IsList l, GHC.Exts.Item l ~ Bool) => l. After unifying, print [True] ends up basically having type (Show a, GHC.Exts.IsList a, GHC.Exts.Item a ~ Bool) => IO (). Notice that the type variable a doesn't appear anywhere to the right of the =>, which makes that an ambiguous type. To make the ambiguity even more concrete, note that in addition to [Bool], the type NonEmpty Bool would also work for a there. The compiler doesn't know which one you want and doesn't want to guess, so it gives you that error. To solve the problem, add a type annotation, like this: main = print ([True] :: [Bool])
For the actual problem in your question, the only differences are that you have the Postable typeclass instead of Show, and the FormParam type instead of Bool. You can fix your problem by replacing the erroring line with res <- post "http://httpbin.org/post" (["num" := (31337 :: Int)] :: [FormParam]).

Haskell read function with no annotation

Does haskell read function implicitly converts a data type into another?
import IO
main = do
putStrLn "Enter an interger: "
num <- getLine
putStr "Value + 3 is "
putStrLn (show((read num) + 3))
So, haskell interpreter automatically changes num's data type from string to int to handle '+ 3'?
read has type Read a => String -> a, which means that it can convert a String into any type that is an instance of the Read type class. Which type it will use depends on the surrounding code. In this case you write read num + 3. The + operator is also overloaded to work for any type that is an instance of Num, so the type of read num + 3 is (Read a, Num a) => a. Haskell has a mechanism that chooses a default type whenever the Num type class remains in the final type of an expression. In this case it defaults to Integer, so the final type is Integer.
You can see this in action by enabling the -Wtype-defaults warning which is also included in -Wall:
Test.hs:5:15: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Show a0) arising from a use of ‘show’ at Test.hs:5:15-34
(Num a0) arising from a use of ‘+’ at Test.hs:5:20-33
(Read a0) arising from a use of ‘read’ at Test.hs:5:21-28
• In the first argument of ‘putStrLn’, namely
‘(show ((read num) + 3))’
In a stmt of a 'do' block: putStrLn (show ((read num) + 3))
In the expression:
do putStrLn "Enter an interger: "
num <- getLine
putStr "Value + 3 is "
putStrLn (show ((read num) + 3))
|
5 | putStrLn (show((read num) + 3))
|
Here you are using
show :: Show a => a -> String
read :: Read a => String -> a
(+) :: Num a => a -> a -> a
3 :: Num a => a
on the same type a. So, Haskell searches for a type a satisfying Show a, Read a, Num a.
In principle, this would be rejected since the type is ambiguous, but Haskell mandates a special rules for Num, causing a to be defaulted, usually to Integer. Since that satisfies also Show and Read, the program type-checks.

How to enforce a type constructor parameter for GHCI

Hello i have the following problem:
I am constructing a parametric newtype over a method and i do not know how to explictly tell GHCI : I want you to instiantiate this newtype using this type parameter
newtype M a = M {fu::a->Int}
var = M (\s-> length (s:"asa")) #tell him i want the type parameter to be Char
b = (fu var) 'c'
What i expect to get is : 4 because length 'c':"aaa"==4
What i do get is :
interactive>:118:5: error:
* Couldn't match expected type `A [Char]'
with actual type `Ghci30.A [Char]'
NB: `Ghci30.A' is defined at <interactive>:100:1-25
`A' is defined at <interactive>:109:1-25
* In the first argument of `fu', namely `b'
In the expression: (fu b) "asa"
In an equation for `it': it = (fu b) "asa"
When you see names like Ghci30.A [Char], this means that you have redefined your type A in GHCi. This would not be an issue if you used a proper .hs file and reloaded it.
Consider this GHCi session:
> data A = A Int
> x = A 2
> data A = A Char -- redefinition
> :t x
What should be the output? The type of x is A, but it's not the same type A having a Char inside. GHCi will print the type as
x :: Ghci0.A
You won't get the error again if you (re-)define x after you redefine the type A.
If your case, the x to be redefined is likely fu, which is still referring to the old A. Check it with :t fu: if it mentions Ghci30.A, that's it.
For non trivial definitions, I'd recommend to use a .hs file and reload it, so to avoid any trouble.

Why doesn't the compiler resolve implicit constrained type variables inside a function?

Here's the code:
class Problem p where
readProblem :: String -> p
solveProblem :: p -> String
readAndSolve = solveProblem . readProblem
And this is the error message GHC yields:
Ambiguous type variable `b0' in the constraint:
(Problem b0) arising from a use of `readProblem'
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `(.)', namely `readProblem'
In the expression: solveProblem . readProblem
In an equation for `readAndSolve':
readAndSolve = solveProblem . readProblem
As I understand, I have to somehow tell the compiler that the Problem instance used by solveProblem and readProblem is the same type, but I see no way to declare that. And why can't it figure that by itself?
You need not tell the compiler that it has to be the same type, the compiler figures that out by itself. However, it can't figure out which type to use. The canonical famous example of the problem is
foo = show . read
If foo had a legal type, that would be
foo :: (Read a, Show a) => String -> String
Now, how could the compiler determine a?
Your readAndSolve would have the type
readAndSolve :: Problem p => String -> String

Resources