Reading the implicit configurations paper (Kiselyov & Shan), I couldn't figure
out how this bit of code (section 3.2) was meant to work:
class Modular s a | s -> a where modulus :: s -> a
normalize :: (Modular s a, Integral a) => a -> M s a
normalize a :: M s a = M (mod a (modulus (undefined :: s)))
Here, `M` is just a type representing a modulus, with a phantom parameter
that's going to make the magic happen:
data M s a = M a deriving (Eq, Show)
Running this in GHC 7.4.2, with the extensions for scope typed variables, multi
parameter type classes, and functional dependencies enabled, I get a parse
error on the type signature on the LHS of the definition of `normalize`. Having
moved the deprecated LHS result annotation to the RHS, I think this should be
equivalent:
normalize :: (Modular s a, Integral a) => a -> M s a
normalize x = (M (mod x (modulus (undefined :: s)))) :: M s a
But indeed this won't type-check. I've tried annotating the argument (x :: a)
and the result of `modulus` (modulus (undefined :: s) :: a), as well as various
other terms, but GHC always tells me the phantom type is ambiguous or the type
of the argument of `normalize` can't be unified with the parameter `a` in the
result type.
Now, like I said, I didn't see how this could work in the first place, so I'm
at a loss as to what the problem is. Can someone show me how to get this to
compile with a recent version of GHC? I'd also appreciate any insight into what
`normalize` is meant to do, if the working code turns out to differ in just a
type annotation or two. ...
Regards,
Eric
PS: The literate Haskell version of the paper is here.
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users