ndmitchell / hlint

Haskell source code suggestions

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pragma annotations and ghci

damiencourousse opened this issue · comments

This is not strictly speaking a bug report.
Here is my question: is it possible to use pragma annotations in code that is read by ghci?

My problem: it looks like I miss something so that ghci correctly reads hlint pragma annotations, assuming this is possible. Here is a stupid but minimal example showing the problem:

module Main where

main :: IO ()
main = do
  print "testing hlint annotations within ghci"
  someFunc >>= print
  
someFunc :: IO Int
someFunc = return 40 >>= return . (+2)
{-# ANN someFunc "HLint: ignore Use fmap" #-}

This code compiles correctly with ghc, and the annotation is correctly processed by the command-line tool hlint, but not by ghci.

$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help

<interactive>:1:1: error:
    Not in scope: ‘System.Console.Editline.Readline.stifleHistory’
    No module named ‘System.Console.Editline.Readline’ is imported.
Loaded GHCi configuration from /home/damien/src/dotfiles/global-haskell/.ghc/ghci.conf
Loaded GHCi configuration from /home/damien/src/dotfiles/global-haskell/.ghci
>>> :l app/Main.hs
[1 of 1] Compiling Main             ( app/Main.hs, interpreted )

app/Main.hs:10:1: error:
    • Ambiguous type variable ‘t0’ arising from an annotation
      prevents the constraint ‘(Data.Data.Data t0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘t0’ should be.
      These potential instances exist:
        instance (Data.Data.Data a, Data.Data.Data b) =>
                 Data.Data.Data (Either a b)
          -- Defined in ‘Data.Data’
        instance Data.Data.Data Ordering -- Defined in ‘Data.Data’
        instance Data.Data.Data Integer -- Defined in ‘Data.Data’
        ...plus 15 others
        ...plus 38 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the annotation: {-# ANN someFunc "HLint: ignore Use fmap" #-}

app/Main.hs:10:18: error:
    • Ambiguous type variable ‘t0’ arising from the literal ‘"HLint: ignore Use fmap"’
      prevents the constraint ‘(Data.String.IsString
                                  t0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘t0’ should be.
      These potential instances exist:
        instance a ~ Char => Data.String.IsString [a]
          -- Defined in ‘Data.String’
        ...plus one instance involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the annotation: {-# ANN someFunc "HLint: ignore Use fmap" #-}
Failed, modules loaded: none.
>>> 


Thanks!! 

Do you have OverloadedStrings turned on? Does putting a type annotation :: String in the annotation fix it?

I think it's an inevitable consequence of how GHC works. Worth noting in the README though.

Am I right in thinking annotations are actually Haskell expressions? Maybe you could introduce an annotation type which would help the type system? I could imagine something like:

{-# ANN module (Ignore "Use fmap") #-}

@ocharles - they are indeed Haskell expressions. But if I add a new constructor it has to be in a library and users have to add a compile time dependency on hlint, which would be a lot sadder than a type annotation.

Ah right, that's quite a gotcha. Thanks for clarifying.