[Haskell-cafe] How to unify these three types with identical structures into one definition?

MarLinn monkleyon at gmail.com
Fri Dec 14 14:51:51 UTC 2018

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

	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.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20181214/47e0b0a1/attachment.html>

More information about the Haskell-Cafe mailing list