haskell / haskell/error-messages
Terrible Arity error messages
- 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