Haskell warning - haskell

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))

Related

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.

Chapter 6, exercise 7, Haskell from first principles

For the following code:
module Main where
data EitherOr a b = Hello a | Goodbye b deriving Show
instance (Eq a, Eq b) => Eq (EitherOr a b) where
(==) (Hello x) (Hello x') = x == x'
(==) (Goodbye x) (Goodbye x') = x == x'
(==) _ _ = False
main :: IO ()
main = do
print (Hello 2 == Hello 2)
-- print (Hello 3 == Hello 2)
-- print (Goodbye 3 == Goodbye 3)
-- print (Goodbye 4 == Goodbye 3)
-- print (Hello 3 == Goodbye 3)
executed under runhaskell, i.e., under ghc, I get the following error:
• Ambiguous type variable ‘b0’ arising from a use of ‘==’
prevents the constraint ‘(Eq b0)’ from being solved.
Probable fix: use a type annotation to specify what ‘b0’ should be.
These potential instances exist:
instance Eq Ordering -- Defined in ‘GHC.Classes’
instance Eq Integer
-- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
instance (Eq a, Eq b) => Eq (EitherOr a b)
-- Defined at /tmp/runghcXXXX61964-0.hs:5:10. <-- This is because I am using org-mode source blocks
...plus 23 others
...plus 11 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘print’, namely ‘(Hello 2 == Hello 2)’
In a stmt of a 'do' block: print (Hello 2 == Hello 2)
In the expression: do print (Hello 2 == Hello 2)
|
12 | print (Hello 2 == Hello 2)
| ^^^^^^^^^^^^^^^^^^
I thought I could give the compiler a type hint by doing
print ((Hello (2 :: Int)) == (Hello (2 :: Int)))
or something similar, but that doesn't seem to be enough. I see that a and b are polymorphic, but I thought the use of == in main might be enough to help the compiler infer types.
Next I loaded the data type and typeclass instance in ghci and explored the types a bit and found that, for instance
λ> :t Hello (2 :: Int)
Hello (2 :: Int) :: EitherOr Int b
As expected. Again in ghci, I do more exploration and see that default types are being used
λ> :t (Hello 2 == Hello 2)
<interactive>:1:2: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:1:2-19
(Num a0) arising from the literal ‘2’ at <interactive>:1:8
• In the expression: (Hello 2 == Hello 2)
<interactive>:1:2: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: (Hello 2 == Hello 2)
(Hello 2 == Hello 2) :: Bool
which is what I want, of course.
Then I actually execute the code in ghci and get the right answer with some defaulting going on
λ> Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:27:1-18
(Num a0) arising from the literal ‘2’ at <interactive>:27:7
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Eq a0) arising from a use of ‘==’ at <interactive>:27:1-18
(Num a0) arising from the literal ‘2’ at <interactive>:27:7
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
• Defaulting the following constraint to type ‘()’
Eq b0 arising from a use of ‘==’
• In the expression: Hello 2 == Hello 2
In an equation for ‘it’: it = Hello 2 == Hello 2
True
But the same code executed under runhaskell, i.e., under ghc compilation, fails with the error I first gave. What do I need to learn here?
The type defaulting rules in GHCi are different than those used when compiling a program such as with GHC. When a type is ambiguous you should give an explicit signature such as:
print (Hello 2 == (Hello 2 :: EitherOr Integer ())
In practice this isn't needed too often because the types are implied by other parts of the program. Toy and educational snippets like the above do not have much in the way of context which could add information for the type checker.

Ambigous type variable that prevents the constraint

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)

Generating a list of random values and printing them to standard output in Haskell

I am pretty new to Haskell and I am struggling to achieve something relatively simple: to generate a list of random numbers and print them to standard output.
Since the random concept is pretty contrary to the function purity in FP world (i.e. methods should return always the same result for the same input), I understand that in this case, the System.Random module in Haskell returns IO actions instead.
My code so far looks like the following:
import System.Random
randomNumber :: (Random a) => (a, a) -> IO a
randomNumber (a,b) = randomRIO(a,b)
main :: IO ()
main = do
points <- sequence (map (\n -> randomNumber ((-1.0), 1.0)) [1..10])
print points
The idea is simple: to generate a list of ten random elements (probably there are better ways to achieve that). My first approach has been creating a function that returns a random number (randomNumber in this case, of type IO a) and using it when mapping over a list of elements (producing a list of IO actions, IO [a]).
From my understanding, sequence (map (\n -> randomNumber ((-1.0), 1.0)) [1..10]) type is IO [a] but I do not know how I can use it. How can I really use points as some value of type [a] instead of IO [a]?
EDIT: Adding the print function within the do "block" produces some errors I don't really know how to get rid of.
Main.hs:8:40:
No instance for (Random a0) arising from a use of ‘randomNumber’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Random Bool -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CChar -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CDouble
-- Defined in ‘System.Random’
...plus 33 others
In the expression: randomNumber ((- 1.0), 1.0)
In the first argument of ‘map’, namely
‘(\ n -> randomNumber ((- 1.0), 1.0))’
In the first argument of ‘sequence’, namely
‘(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10])’
Main.hs:8:55:
No instance for (Num a0) arising from a use of syntactic negation
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 37 others
In the expression: (- 1.0)
In the first argument of ‘randomNumber’, namely ‘((- 1.0), 1.0)’
In the expression: randomNumber ((- 1.0), 1.0)
Main.hs:8:56:
No instance for (Fractional a0) arising from the literal ‘1.0’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Fractional Double -- Defined in ‘GHC.Float’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus three others
In the expression: 1.0
In the expression: (- 1.0)
In the first argument of ‘randomNumber’, namely ‘((- 1.0), 1.0)’
Main.hs:9:9:
No instance for (Show a0) arising from a use of ‘print’
The type variable ‘a0’ is ambiguous
Relevant bindings include points :: [a0] (bound at Main.hs:8:9)
Note: there are several potential instances:
instance Show Double -- Defined in ‘GHC.Float’
instance Show Float -- Defined in ‘GHC.Float’
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
...plus 65 others
In a stmt of a 'do' block: print points
In the expression:
do { points <- sequence
(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10]);
print points }
In an equation for ‘main’:
main
= do { points <- sequence
(map (\ n -> randomNumber ((- 1.0), 1.0)) [1 .. 10]);
print points }
Failed, modules loaded: none.
Why does this happen?
There is one particular message in all your errors: The type variable ‘a0’ is ambiguous. Why is this the case? Well, randomNumber works for any instance of Random, and there are a bunch of instances. -1.0 includes Num, since you want to be able to negate a value. Also, the value 1.0 itself concludes that your type needs to be an instance of Fractional. That reduces the amount of types that can be used in this circumstance, but it's still not unique: Float, Double and four others are suitable.
At this point, the compiler gives up, and you need to tell it what instance you actually want to use.
How to fix this
There are many ways to fix this. For one, we could introduce a small helper function:
-- fix a to double
randomDouble :: (Double, Double) -> IO Double
randomDouble = randomNumber
Or we could annotate the type of the ambiguous 1.0:
points <- sequence (map (\n -> randomNumber ((-1.0), 1.0 :: Double)) [1..10])
-- ^^^ as a Double
Or we could annotate the type of the list:
print (points :: [Double])
-- ^^^^^^^^^^^^^^^^^^ points is a list of Doubles
Which one you choose is actually more or less a matter of style and personal preference. That being said, sequence . map f $ xs can be written as mapM f xs, but since you actually have IO a, you're better of with replicateM $ randomNumber (...). Both mapM and replicateM can be found in Control.Monad.
TL;DR
When GHC yells at you for ambiguous types, annotate them.
A couple points:
You called the function randomNumber, but allowed it to take any type that is a part of the Random class (including Chars etc.). If you do only want it to take numbers, you should change the signature to match its purpose (randomNumber :: (Int,Int) -> IO Int) or more generically, randomNumber :: (Num n. Random n) => (n,n) -> IO n
sequence takes a list of actions ([IO a]), and returns a list in the IO monad (IO [a]). It basically just executes each action, stores the result, then re-wraps the list in IO. You could try something like replicateM 10 $ randomNumber (1,10). replicateM takes an Int and an action to carry out, and returns a list of executed actions (as Zeta pointed out, sequence is used internally in a call to replicateM).
(And code blocks aren't working for me for some reason, so I wrote everything as "infix code".)

Resources