[Haskell-cafe] could not deduce Show compile error
Henning Thielemann
lemming at henning-thielemann.de
Fri Jun 2 14:21:02 UTC 2023
On Fri, 2 Jun 2023, Zoran BoĆĄnjak wrote:
> import Prelude hiding ((.), id)
> import Control.Category
>
> data Flow a b where
> Id :: Flow a a
> Compose :: Flow a b -> Flow b c -> Flow a c
type variable 'b' of Compose is not visible outside Flow. Thus you cannot
get later in runFlow, but you have to embed the Show constraint in the
Compose constructor like so:
Compose :: (Show b) => Flow a b -> Flow b c -> Flow a c
But this in turn means, you can compose only Flows where the interim type
'b' is an instance of Show.
To avoid this you would need an additional type parameter to Flow with a
constraint kind constructor or an existentially quantified type, that
holds all the constraints you need for your current application.
I think it should be like so:
type family FlowConstraints constr a
data FlowAny
type instance FlowConstraints FlowAny a = ()
data FlowShow
type instance FlowConstraints FlowShow a = (Show a)
data Flow constr a b where
Id :: Flow a a
Compose :: (FlowConstraints constr b) => Flow a b -> Flow b c -> Flow a c
or alternatively:
data family FlowConstraints constr a
data FlowAny
data instance FlowConstraints FlowAby a = FlowAnyConstraint
data FlowShow
data instance FlowConstraints FlowShow a = (Show a) => FlowShowConstraint
data Flow constr a b where
Id :: Flow a a
Compose :: (FlowConstraints constr b) => Flow a b -> Flow b c -> Flow a c
In this case you have to match on FlowAnyConstraint or FlowShowConstraint
in runFlow in order to get back the required constraints.
In any case, the constraints must already be available at construction
with Compose. Thus you will not be able to use Compose in a Category
instance.
More information about the Haskell-Cafe
mailing list