Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terrible Arity error messages #546

Open
noughtmare opened this issue Aug 26, 2023 · 0 comments
Open

Terrible Arity error messages #546

noughtmare opened this issue Aug 26, 2023 · 0 comments

Comments

@noughtmare
Copy link

noughtmare commented Aug 26, 2023

I just encountered this one:

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant