[Haskell-cafe] Avoiding parametric function binding

Sebastian Fischer fischer at nii.ac.jp
Sun Jan 1 13:29:42 CET 2012


On Sat, Dec 31, 2011 at 4:09 PM, Kevin Quick <quick at sparq.org> wrote:

>
>  onVarElem :: forall a . (Show a) => (Maybe a -> String) -> Var -> String
>> onVarElem f (V1 x) = f x
>> onVarElem f (V2 x) = f x
>>
>> main = putStrLn . onVarElem elemStr $ test
>>
>
> This is probably a better design, but still fails for the same reason:
>
>    Couldn't match expected type `Int' with actual type `[Char]'
>    Expected type: Maybe Int
>      Actual type: Maybe String
>    In the first argument of `f', namely `x'
>    In the expression: f x


The problem is the scope of the quantification of the type variable 'a'.
You can use higher-rank types (via the Rnak2Types or RankNTypes language
extension) to achieve what you want. Change the type of 'onVarElem' to

    onVarElem :: (forall a . (Show a) => Maybe a -> String) -> Var -> String

In contrast to the previous type, this type says that the provided function
must be polymorphic over Show instances 'a', while the previous type would
have allowed any specialization of 'a' with a Show instance.

With the previous type, the call

    onVarElem (maybe show (show . not))

would have been legal, with the new type it is not, which is necessary for
the implementation to be well typed.

If you don't want to use a language extension that allows you to require
polymorphism on function arguments, then Stephen's solution is a good
workaround.

Sebastian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120101/bc644741/attachment.htm>


More information about the Haskell-Cafe mailing list