ndmitchell / hlint

Haskell source code suggestions
Other
1.45k stars 194 forks source link

Don't suggest replacing `if … else if … else` with guards when `RebindableSyntax` is enabled #1559

Open cbjeukendrup opened 5 months ago

cbjeukendrup commented 5 months ago

In the following minimal example:

{-# LANGUAGE RebindableSyntax #-}

module Main where

import Prelude

data MyBool = MyTrue | MyFalse

ifThenElse :: MyBool -> a -> a -> a
ifThenElse MyTrue = const
ifThenElse MyFalse = flip const

main :: IO ()
main = do
  let isOne = MyTrue
  let isTwo = MyFalse
  print $ myNumber isOne isTwo

myNumber :: MyBool -> MyBool -> Int
myNumber isOne isTwo =
  if isOne
    then 1
    else
      if isTwo
        then 2
        else 3

HLint suggests replacing the definition of myNumber with the following:

myNumber isOne isTwo
  | isOne = 1
  | isTwo = 2
  | otherwise = 3

That does not compile though: guards (sadly?) only work with real bools, while if … then … else works with whatever type for which ifThenElse is available.

Perhaps the "Use guards" suggestion should not be given when the if … then … else syntax is rebound.

ndmitchell commented 5 months ago

Unfortunately this is a known limitation - see https://github.com/ndmitchell/hlint#bugs-and-limitations - RebindableSyntax and HLint don't play great together. It might be possible to detect a file is in rebindable mode and disable some hints. Let's use this issue for that work.