Benjamin Franksen wrote:
>Functions with implicit parameters *are* first class values but only if you
>use -fglasgow-exts and not only -fimplicit-params.
Careful, they're still not entirely first class. For example, you can't pass types with implicit parameters as arguments to type constructors, so "IO ((?val::Bool) => String)" will still be rejected, even with -fglasgow-exts.
(While experimenting with this, I discovered to my surprise that GHCi accepts the type "IO ((Num a) => a)", and describes it as "forall a. IO ({Num a} => a)". However it rejects "return 12 :: IO ((Num a) => a)", saying that it can't deduce (Num ({Num a} => a)). Is this a bug?)
>The version above is
>rejected nonetheless (for whatever reason I can't figure out at the moment)
There's actually a good reason for this. The three declarations
data (?val::Bool) => Test = Test { name :: String }
data Test = (?val::Bool) => Test { name :: String }
data Test = Test { name :: (?val::Bool) => String }all mean different things.
The first one makes (?val::Bool) a constraint on the type constructor Test, meaning that any type that mentions Test will be required to have a (?val::Bool) context also. This is basically useless in practice, since it just adds a dummy function parameter which is (in general) never actually used. Type-class constraints in this position are deprecated, and I guess implicit-parameter constraints were never allowed in the first place.
The second declaration makes (?val::Bool) a constraint on the *data* constructor Test, so the data constructor gets the type (?val::Bool) => String -> Test. The constructor stores the value of ?val in a second quasi-hidden field in the constructed value. When it's later deconstructed by pattern matching, the value becomes "available" again, even though it doesn't appear explicitly in the pattern. This has a clear semantics for type-class constraints because they are always attached to particular explicit values, but I don't know how much sense it makes for implicit parameters.
The third declaration makes (?val::Bool) a constraint on a particular *field* of the data constructor, so Test has the type ((?val::Bool) => String) -> Test. This simply constrains the type of that field. There are no extra hidden fields.
-- Ben
_______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
