2

I've been mucking around with implicit parameters which I've sometimes found useful, but trying to do something like the code below (which doesn't compile)

{-# LANGUAGE ImplicitParams #-}

main = print (f z)

f g =
  let 
    ?x = 42
    ?y = 5
  in
    g

z :: (?x :: Int) => Int
z = ?x

What I want basically is a function f which runs a given function with a "context". In the case above, f z will run z with ?x = 42, which naturally just returns 42 in this case and hence this program should print 42. But I get the error:

• Unbound implicit parameter ?x::Int arising from a use of ‘z’
• In the first argument of ‘f’, namely ‘z’
  In the first argument of ‘print’, namely ‘(f z)’
  In the expression: print (f z)

This is because there's no context for z where it's first used in main, even though f is providing the context.

The reason I'm attempting to do this is because I've got a number of functions which work with implicit parameters, and a GADT which has differing but similar implementation options. It's relatively trivial to write a function which extracts the appropriate implicit parameters from each of the possible GADT constructors, but then I want to apply a function with those implicit parameters.

Something like this approach (that compiles) would be good, or alternatively a different approach which allows me to easily set an implicit parameter context for a variety of functions would also be fine.

Clinton
  • 22,361
  • 15
  • 67
  • 163

1 Answers1

3

You need an explicit type annotation for f. GHC isn't able to infer the right type.

{-# LANGUAGE ImplicitParams, Rank2Types #-}

main = print (f z)

f :: ((?x :: Int, ?y :: Int) => a) -> a
f g =
  let 
    ?x = 42
    ?y = 5
  in
    g

z :: (?x :: Int) => Int
z = ?x
chi
  • 111,837
  • 3
  • 133
  • 218