[Haskell-cafe] [Q] multiparam class undecidable types
Matthias Fischmann
fis at etc-network.de
Wed May 9 13:57:17 CEST 2012
Thanks Oleg,
that was very helpful. i can work with that. read the rest of this
if you are curious where your hints took me.
you are right, I need to make the functional dependency explicit:
| class Table t c | t -> c where
| toLists :: t -> [[c]]
| fromLists :: [[c]] -> t
|
| instance Table [[c]] c where
| toLists = id
| fromLists = id
|
| instance (Table t c, Show c) => Show t where
| showsPrec p t = showParen (p > 10) $ showString "fromLists " . shows (head . head $ toLists t)
this compiles, and 'show' prints the first cell of each table. i also
understand now why i can't just print all of them: [[Int]] is one of
the types where the instances overlap.
| instance Show Int
| instance Show a => Show [a]
vs.
| instance Table [[Int]] Int
| instance (Table [[Int]] Int, Show Int) => Show [[Int]]
the advanced overlap code you are referencing below is fascinating,
but isn't it a different problem? i don't want to distinguish
different the cases "Show c" and "Typeable c", but i want to use
whatever instance of "Show c" is available to implement "Show t".
i can't make your solution work for this, because one of the two
overlapping instances (namely "Show a => Show [a]") is already
provided by the surrounding code that i cannot outfit with the
advanced overlap trick. or am i missing something here?
i think what i will do is to instantiate all table types individually:
| instance Show c => Show (SimpleTable c) where
| showsPrec p t = showParen (p > 10) $ showString "FastTable " .
| shows (toLists t)
cheers,
matthias
On Wed, May 09, 2012 at 06:41:00AM -0000, oleg at okmij.org wrote:
> Date: 9 May 2012 06:41:00 -0000
> From: oleg at okmij.org
> To: fis at etc-network.de
> CC: haskell-cafe at haskell.org
> Subject: Re: [Q] multiparam class undecidable types
>
>
> > | instance (Table a c, Show c) => Show a where
> > I would have thought that there is on overlap: the instance in my code
> > above defines how to show a table if the cell is showable;
>
> No, the instance defines how to show values of any type; that type
> must be an instance of Table. There is no `if' here: instances are
> selected regardless of the context such as (Table a c, Show c)
> above. The constraints in the context apply after the selection, not
> during.
>
> Please see
> ``Choosing a type-class instance based on the context''
> http://okmij.org/ftp/Haskell/TypeClass.html#class-based-overloading
>
> for the explanation and the solution to essentially the same problem.
>
> There are other problems with the instance:
>
> | instance (Table a c, Show c) => Show a where
>
> For example, there is no information for the type checker to determine
> the type c. Presumably there could be instances
> Table [[Int]] Int
> Table [[Int]] Bool
> So, when the a in (Table a c) is instantiated to [[Int]]
> there could be two possibilities for c: Int and Bool. You can argue
> that the type of the table uniquely determines the type of its
> cells. You should tell the type checker of that, using functional
> dependencies or associated types:
>
> class Table table where
> type Cell table :: *
> toLists :: table -> [[Cell table]]
>
>
>
More information about the Haskell-Cafe
mailing list