[Haskell-cafe] How to unify these three types with identical structures into one definition?
will.yager at gmail.com
Sat Dec 15 12:58:33 UTC 2018
There may be some fun to be had with QuantifiedConstraints. I've thought
about solving similar parser/formatter problems this way, extending parsers
via functor composition. Consider:
> data F f = F (f (F f))
> -- Sadly the below does not work. It seems like maybe it should be able
> instance (forall a . Show a => Show (f a)) => Show (F f) where show (F f)
= "(F " ++ show f ++ ")"
• The constraint ‘Show (f a)’
is no smaller than the instance head ‘Show (F f)’
(Use UndecidableInstances to permit this)
• In the instance declaration for ‘Show (F f)’
> -- We can get something almost as good
> class (forall a . Show a => Show (f a)) => Show1 f
> instance Show1 f => Show (F f) where show (F f) = "(F " ++ show f ++ ")"
> instance Show1 Maybe
> show (F $ Just $ F $ Nothing)
"(F Just (F Nothing))"
On Fri, Dec 14, 2018 at 10:52 PM MarLinn <monkleyon at gmail.com> wrote:
> Hi Ducis,
> you can parametrise over type variables of other kinds than just *.
> If what you write is really what you want, the most straightforward answer
> is simply
> data ExprG f
> = Var VarName
> | Enclosed VarName (f Expr) VarName
> | Prefix (f Expr) (f Expr)
> | Ternary (f Expr) VarName (f Expr) VarName (f Expr)
> type Expr = ExprG Identity -- From Data.Functor.Identity
> type ExprL = ExprG 
> type ExprD = ExprG DList
> There is no mention of the word "functor" because you will have to add
> that constraint to the usage sites.
> Downside: notice that the deriving clauses are gone because the instances
> aren't as easy to derive any more. Even the simplest and most harmless way
> I know to get that possibility back involves two language extensions:
> StandaloneDeriving and FlexibleInstances. With those you can write
> deriving instance Show (ExprG Identity)
> deriving instance Show (ExprG )
> deriving instance Show (ExprG DList)
> deriving instance Eq (ExprG Identity)
> I suspect though that what you actually want, but didn't write, is more
> along the lines of
> data ExprL = … | EnclosedL VarName [ExprL] VarName | … -- using ExprL instead of Expr on the right side
> data ExprD = … | EnclosedD VarName (DList ExprD) VarName | … -- using ExprD instead of Expr on the right side
> The good news is that if you have the first solution, this step is rather
> simple. Because you can just use replace Expr with ExprG f again:
> data ExprG f
> = Var VarName
> | Enclosed VarName (f (ExprG f)) VarName
> | Prefix (f (ExprG f)) (f (ExprG f))
> | Ternary (f (ExprG f)) VarName (f (ExprG f)) VarName (f (ExprG f))
> The better news is that although this looks repetitive and hard to read,
> it's well on the way to discovering the magic of the Free Monad.
> Hope this helps.
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe