type error in func declaration - haskell

I do:
Prelude> "sone" ++ "otehr"
"soneotehr"
But such code:
addOneToElement :: [a] -> [a]
addOneToElement element = element ++ "next"
main = do
let s = addOneToElement("some")
putStrLn s
produces this output:
all_possible_combinations.hs:22:37:
Couldn't match expected type `a' against inferred type `Char'
`a' is a rigid type variable bound by
the type signature for `addOneToElement'
at all_possible_combinations.hs:21:20
Expected type: [a]
Inferred type: [Char]
In the second argument of `(++)', namely `"next"'
In the expression: element ++ "next"
Why I get this error and how I can fix it?

Your type signature should be:
addOneToElement :: [Char] -> [Char]
(Or more simply, addOneToElement :: String -> String)
The "a" in your type signature is a wildcard - it can match anything. However you are trying to concatenate a list of Char to a list of anything - and there is no way to do that.

Why are you using a type variable here anyway? The only type that can match is Char, since the second operand of (++) is fixed to [Char] ("next").

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

read::Int not working in Haskell in example

Here is the problem. It looks simple yet
main = do
s <- getContents
let list = map (read::Int) (words s)
print list
Couldn't match expected type `Int' with actual type `String -> a0'
Probable cause: `read' is applied to too few arguments
In the first argument of `map', namely `(read :: Int)'
In the expression: map (read :: Int) (words s)
The problem was that I thought :: is like casting and I have to put the return type. The solution was to add full wanted |function signature instread.
read is a function (of type Read a => String -> a), so it can't have type Int. You could do read :: String -> Int, or you could put a type signature on list rather than read, so you get:
let list :: [Int]
list = map read (words s)

Couldn't match expected type `Int' with actual type `IO [Int]'

Can someone please explain what's going on in my function.
arrayReader :: [Int] -> IO [Int]
arrayReader arr = do
item <- readLn
return $ if item == 0
then arr
else arrayReader item:arr
But Haskell is not happy with the 6th line:
reader.hs:6:17:
Couldn't match expected type `Int' with actual type `IO [Int]'
In the return type of a call of `arrayReader'
In the first argument of `(:)', namely `arrayReader item'
In the expression: arrayReader item : arr
Can someone explain what needs to be changed to make this function compile?
Firstly, you have a precedence error - arrayReader item:arr parses as (arrayReader item):arr. You need to write arrayReader (item:arr).
Secondly, arrayReader produces something of type IO [Int], but in this context return takes something of type [Int] and produces IO [Int]. You need to rearrange your code so that return is only called on arr, not on the result of arrayReader.

Can't compile because of types when using nub, map and take

I've got this simple function:
bombplaces::Int->[(Int,Int)]->[(Int,Int)]
bombplaces bombCount listOfPossiblePoints = nub (map (take bombCount) (perms listOfPossiblePoints))
bombs are (x,y) (carthesian points)
i need to get an all permutations and take only first few (bombCount) points.
I'm getting following error:
Couldn't match expected type `(Int,Int)' with actual type `[a0]'
Expected type: [a0] -> (Int,Int)
Actual type: [a0] -> [a0]
In the return type of a call of `take'
In the first argument of `map', namely `(take liczbaBomb)'
If you remove the type signature and ask GHCi for the type, your problem will be obvious:
> :t bombplaces
bombplaces :: Eq a => Int -> [a] -> [[a]]
That is, bombplaces wants to return a list of lists whereas you want it to return a plain list. You need to either change the type signature, or change the definition of the function, depending on what you want the behaviour to be.
N.B. You didn't tell us what definition of perms you are using, so I assumed the obvious one.

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