Passing values taking implicit parameters

Mike Gunter m@ryangunter.com
30 Jan 2002 21:35:41 -0800


I'd like write a function taking values with implicit parameters.  I can't get this to work in a
straightforward way in GHC 5.02 (with -fno-monomorphism-restriction.)  In particular, if I try:

> wF :: ((?x :: Int) => a) -> Int -> a	-- compiles but tf won't work
> wF s z = s with ?x = z
> 
> f :: (?x :: Int) => Int
> f = (?x + 3)
> -- tf :: Int 				-- If uncommented GHC fails because can't deduce context (?x::Int) 
> -- tf :: (?x :: Int) => Int		-- Type GHC assigns to tf
> tf = wF f 8				-- Trying to evaluate gives: "Unbound implicit parameter (?x :: Int)"

Trying to evaluate tf gives: "Unbound implicit parameter (?x :: Int)"


On the other hand, if the passed value has another class in its context, things work as expected:

> wF' :: Integral a => (forall a . (Integral a, ?x :: Int) => a) -> Int -> a
> wF' s z = s with ?x = z
> f' :: (Integral a, ?x :: Int) => a
> f' = fromIntegral (?x + 3)
> tf' = wF' f' 8			-- GHCi gives me 11, as expected


At the cost of having to wrap each value with an extra call (to "dummy" here), I seem to be able to get the
desired effect for general types with this code:

> class DummyCl c		where dummy :: a -> c a
> newtype Dummy a	= Dummy { unDummy :: a }
> instance DummyCl Dummy	where dummy = Dummy
> 
> wF'' :: (forall c . (DummyCl c, ?x :: Int) => c a) -> Int -> a
> wF'' s z = unDummy (s with ?x = z)

> -- f'' :: (DummyCl c, ?x :: Int) => c Int	-- Type signature unnecessary
> f'' = dummy f

> tf''	= wF'' f'' 100				-- evaluates

> fHO	= dummy (?x +)
> tfHO	= (wF'' fHO 31) 22			-- evaluates

> tf''' = wF'' (dummy f) 1000			-- gets: "Unbound implicit parameter (?x :: Int)" 
> tf4	= wF'' (dummy (?x + 7)) 300		-- evaluates
> tfHO'	= (wF'' (dummy (show . (?x +))) 50) 63	-- evaluates



So my questions are: Is there a straightforward way to pass values taking implicit parameters in GHC?  And, if
not, is there a better workaround than my "dummy" code above?

        thanks,
        mike