haskell / haskell/error-messages

Errors from confusing whether to use `let` or `bind`

Open
#37 5 comments 0 reactions 0 assignees View on GitHub
status:Composing error message tool:GHC type:error-message
Dominant language
No language data
Stars
76
Forks
19
PR merge metrics
No merged PRs in 30d

Description

I am quite sure I've seen more cryptic error messages, but for now I can only found simpler ones.

# Problem

I noticed that there are many errors coming from confusion between:

```hs
do
foo <- bar baz
useFoo foo
```
vs.
```hs
do
let foo = bar baz
useFoo foo
```

It would be great if we could give a suggestion.

# Cases and Errors

StackOverflow search gave a few such cases.

1.
Code:
```hs
parseDnsMessage :: BG.BitGet DnsMessage

recQuery :: BS.ByteString -> String -> IO BS.ByteString

resolveName :: [Word8] -> [Word8] -> BS.ByteString -> String
resolveName qname name bstr = do
let newbstr = BSL.toStrict $ replace (BS.pack qname) (BS.pack name) bstr
retbstr <- recQuery newbstr (head rootServers4)
let msg = BG.runBitGet retbstr parseDnsMessage
case msg of
Right m -> (intercalate "." $ map show (rdata $ head $ answer $ m))
```

Error message:
```
Couldn't match expected type ‘[BSI.ByteString]’
with actual type ‘IO BSI.ByteString’
In a stmt of a 'do' block:
retbstr <- recQuery newbstr (head rootServers4)
In the expression:
do { let newbstr
= BSL.toStrict $ replace (BS.pack qname) (BS.pack name) bstr;
retbstr <- recQuery newbstr (head rootServers4);
let msg = BG.runBitGet retbstr parseDnsMessage;
case msg of {
Right m
-> (intercalate "." $ map show (rdata $ head $ answer $ m)) } }
```

2.
Code:
```hs
title :: IO Html
title = do
y <- getCurrentYear
return $ toHtml $ "Registration " ++ y

getRootR :: Handler RepHtml
getRootR = do
(widget, enctype) <- generateFormPost personForm -- not important for the problem at hand, comes from the example in the yesod book
defaultLayout $ do
setTitle title -- this is where I get the type error
[...]
```

Error:
```
Couldn't match expected type `Html' with actual type `IO Html'
In the first argument of `setTitle', namely `title'
[...]
```
(You know there is no suggestion in `...` part)

This one is special in that they are trying to use top-level IO action. still, likely a similar fix.

3.
Code:
```hs
displayList :: [Int] -> IO()
displayList [] = putStrLn ""
displayList (firstUnit:theRest) = putStrLn (show firstUnit ++ "\n" ++
displayList theRest)
```

Error:
```
• Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
• In the second argument of ‘(++)’, namely ‘(displayList theRest)’
In the first argument of ‘putStrLn’, namely
‘((show firstUnit) ++ (displayList theRest))’
In the expression:
putStrLn ((show firstUnit) ++ (displayList theRest))
```

# Suggestion
Let me consider the last one.
```
Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
In the second argument of ‘(++)’, namely ‘(displayList theRest)’
In the first argument of ‘putStrLn’, namely
‘((show firstUnit) ++ (displayList theRest))’
In the expression:
putStrLn ((show firstUnit) ++ (displayList theRest))
```

Perhaps add suggestion like this:

```
Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
Perhaps you would like to bind `displayList theRest` in the do notation.
In the second argument of ‘(++)’, namely ‘(displayList theRest)’
[...]
```
(Though, I do not like the word `bind` here)

or this:
```
Couldn't match expected type ‘[Char]’ with actual type ‘IO ()’
Suggested fix: use `<-` in do notation.
In the second argument of ‘(++)’, namely ‘(displayList theRest)’
[...]
Perhaps you want to use:
do
d <- displayList theRest
-- use d here
instead of:
(displayList theRest)
in the expression.
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.