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

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.

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 `IO ()' with actual type `a0 -> m0 a0'

Here's my code:
doSomething :: IO Bool -> IO () -> IO ()
doSomething cond body = cond >>= ( \condition -> if condition then return else body )
It gives me this error:
Couldn't match expected type `IO ()' with actual type `a0 -> m0 a0'
In the expression: return
In the expression: if condition then return else body
In the second argument of `(>>=)', namely
`(\ condition -> if condition then return else body)'
I also tried this equivalent notation:
whileM :: IO Bool -> IO () -> IO ()
whileM cond body = do
condition <- cond
if condition then return else body
but I am getting more or less the same notation. I understand that the error is saying that the function expects me to return a Monad but instead I am returning a function which transforms a0 into a monad m a0. How can I fix this?
Unlike in (pretty much all) other languages, in Haskell, return doesn't mean "terminate this code and go back to the next line of what called it".
In Haskell, it (roughly) means "wrap this thing up in a monad". In the context of the do notation, this often occurs at the place in the code where control is given back to the "caller" (again, this isn't really the correct word, but will do in this analogy).
Hence, return needs a parameter here (the thing to be wrapped up).... return is of type Monad m => a -> m a, but your function is returning type IO (). The thing you will therefore need to wrap up is of type (), a type with just one element, '()' itself.
Change return to return (), and see if that works.

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.

type error in func declaration

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

Resources