[Haskell-cafe] OverloadedStrings mixed with type classes leads toboilerplate type signatures

Claus Reinke claus.reinke at talk21.com
Mon Dec 6 00:02:46 CET 2010


>    ghci> :set -XOverloadedStrings
>    ghci> "$name ate a banana." % [("name", "Johan")]
>    "Johan ate a banana."

>    class Context a where
>        lookup :: a -> T.Text -> T.Text
>
>    instance Context [(T.Text, T.Text)] where
>        lookup xs k = fromMaybe (error $ "KeyError: " ++ show k) (P.lookup 
> k xs)

This instance only applies if the pair components are Texts.

With OverloadedStrings, your unannotated String-like Pairs
have variable type components, so the instances neither
matches nor forces the type variables to be Text.

It sounds as if you want an instance that always applies for
lists of pairs, instantiates type variable components to Texts,
and fails if the components cannot be Texts. Untested:

    instance (key~T.Text,value~T.Text) => Context [(key, value)] where

You might also want to parameterize Context over the
type of template, but then you might need to annotate
the template type, or use separate ops for different types
of template?

Claus

>    -- > "$foo" % [("foo" :: T.Text, "bar" :: T.Text)]
>    (%) :: Context c => T.Text -> c -> LT.Text
>    (%) = undefined
>
> The problem is that the compiler is not able to deduce that string
> literals should have type 'Text' when used in 'Context's. For example
>
>    ghci> :t "$foo" % [("foo", "bar")]
>
>    <interactive>:1:8:
>        No instance for (Context [(a, a1)])
>          arising from a use of `%'
>        Possible fix: add an instance declaration for (Context [(a, a1)])
>        In the expression: "$foo" % [("foo", "bar")]
>
> This forces the user to provide explicit type signatures, which makes
> the construct more heavy weight and defeats the whole purpose of
> introducing the 'Context' class:
>
>    ghci> :t "$foo" % [("foo" :: T.Text, "bar" :: T.Text)]
>    "$foo" % [("foo" :: T.Text, "bar" :: T.Text)] :: LT.Text
>
> Is there any way to make the syntactically short `"$foo" % [("foo",
> "bar")]` work but still keep the 'Context' class?
>
> Johan
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>

 




More information about the Haskell-Cafe mailing list