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