haskell / haskell/error-messages

Terrible Arity error messages

Open
#546 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
76
Forks
19
PR merge metrics
No merged PRs in 30d

Description

I just encountered this one:

```haskell
import Data.Primitive.SmallArray
import Data.Primitive.PrimArray
import Data.Primitive (Prim)

smallToPrim :: Prim b => (a -> b) -> SmallArray a -> PrimArray b
smallToPrim f xs = runPrimArray $ do
let n = length xs
s <- newPrimArray n
let
go i
| i < n = do
writePrimArray s (f (indexSmallArray xs i))
go (i + 1)
| otherwise = pure ()
go 0
pure s
```

With the error:

```
app/Main.hs:12:27: error: [GHC-25897]
• Couldn't match expected type ‘Int’ with actual type ‘b’
‘b’ is a rigid type variable bound by
the type signature for:
smallToPrim :: forall b a.
Prim b =>
(a -> b) -> SmallArray a -> PrimArray b
at app/Main.hs:5:1-64
• In the second argument of ‘writePrimArray’, namely
‘(f (indexSmallArray xs i))’
In a stmt of a 'do' block:
writePrimArray s (f (indexSmallArray xs i))
In the expression:
do writePrimArray s (f (indexSmallArray xs i))
go (i + 1)
• Relevant bindings include
go :: Int -> b -> () (bound at app/Main.hs:10:5)
s :: MutablePrimArray (Control.Monad.Primitive.PrimState m0) b
(bound at app/Main.hs:8:3)
f :: a -> b (bound at app/Main.hs:6:13)
smallToPrim :: (a -> b) -> SmallArray a -> PrimArray b
(bound at app/Main.hs:6:1)
|
12 | writePrimArray s (f (indexSmallArray xs i))
| ^^^^^^^^^^^^^^^^^^^^^^^^

app/Main.hs:15:3: error: [GHC-83865]
• Couldn't match expected type: GHC.ST.ST s a0
with actual type: b -> ()
• Probable cause: ‘go’ is applied to too few arguments
In a stmt of a 'do' block: go 0
In the second argument of ‘($)’, namely
‘do let n = length xs
s <- newPrimArray n
let go i
| i < n = ...
| otherwise = pure ()
go 0
....’
In the expression:
runPrimArray
$ do let n = length xs
s <- newPrimArray n
let go i
| i < n = ...
| otherwise = pure ()
go 0
....
• Relevant bindings include
go :: Int -> b -> () (bound at app/Main.hs:10:5)
s :: MutablePrimArray (Control.Monad.Primitive.PrimState m0) b
(bound at app/Main.hs:8:3)
f :: a -> b (bound at app/Main.hs:6:13)
smallToPrim :: (a -> b) -> SmallArray a -> PrimArray b
(bound at app/Main.hs:6:1)
|
15 | go 0
| ^^^^
```

The real problem here is that I forgot to supply the index for `writePrimArray`:

```
writePrimArray s i (f (indexSmallArray xs i))
^
```

So GHC is committing too soon to the wrong arity for `go` . I think GHC should not be guessing the arity of functions in case of type errors, it should be strongly biased towards keeping the same arity as the user has written.

GHC could also spot that the type `b` of the expression `(f (indexSmallArray xs i))` would fit if there was another argument applied before it. Perhaps we could in general make error messages better for cases where arguments to a function are swapped or forgotten.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the app/Main.hs example and reproduce the diagnostics involving GHC-25897 and GHC-83865. Compare the reported arity with the corrected writePrimArray call and determine how the compiler currently infers go's type. Done means the same example produces an actionable diagnostic that preserves the written arity or identifies the missing argument.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.