Skip to content

Simplified subsumption hurts ImplicitParams usability

Motivation

Under GHC 8.10.7, the following code compiles but under GHC 9.0.1, due to simplified subsumption, it fails to compile. The function bar has an error but the function baz, the eta-expanded version of bar, is fine. The need to do eta-expansion makes ImplicitParams unergonomic to use.

{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE RankNTypes #-}

module Lib where

foo :: Int -> ((?self :: Int) => Char) -> Char
foo x y = undefined

bar :: Int -> (Char -> Char)
bar x = ((let ?self = x in foo) :: Int -> Char -> Char) x

baz :: Int -> (Char -> Char)
baz x = (let ?self = x in (\u v -> foo u v)) x

ERROR

/home/jchia/gh/ip-bug/src/Lib.hs:10:28: error:
    • Couldn't match type ‘(?self::Int) => Char’ with ‘Char’
      Expected: Int -> Char -> Char
        Actual: Int -> ((?self::Int) => Char) -> Char
    • In the expression: foo
      In the expression: (let ?self = x in foo) :: Int -> Char -> Char
      In the expression:
        ((let ?self = x in foo) :: Int -> Char -> Char) x
   |
10 | bar x = ((let ?self = x in foo) :: Int -> Char -> Char) x

Proposal

Modify GHC or the mechanics of simplified subsumption somehow to allow ImplicitParams to be used the same way is in GHC 8.10.7. However, I am not proposing the actual mechanics to achieve this, which is a matter for discussion.

Edited by jchia
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information