[Haskell-cafe] Bool as type class to serve EDSLs.

Simon Peyton-Jones simonpj at microsoft.com
Thu May 28 03:14:28 EDT 2009


You are absolutely right about the tantalising opportunity.  I know that Lennart has thought quite a bit about this very point when designing his Paradise system.  Likewise Conal for Pan.

One difficulty is, I think, that it's easy to get ambiguity.  Eg
        ifthenelse (a > b) e1 e2
The (a>b) produces a boolean-thing, and ifthenelse consumes it; but which type of boolean?  The Expr type?  Real Bools? Or what?

If there was a nice design, then GHC's existing -fno-implicit-prelude flag could be extended (again) to desugar if-then-else to the new thing.  But the design is unclear, to me anyway.

Simon

| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org [mailto:haskell-cafe-bounces at haskell.org] On
| Behalf Of Sebastiaan Visser
| Sent: 27 May 2009 13:32
| To: Haskell Cafe
| Subject: [Haskell-cafe] Bool as type class to serve EDSLs.
|
| Hello,
|
| While playing with embedded domain specific languages in Haskell I
| discovered the Num type class is a really neat tool. Take this simple
| example embedded language that can embed primitives from the output
| language and can do function application.
|
|  >data Expr :: * -> * where
|  >  Prim :: String -> Expr a
|  >  App  :: Expr (a -> b) -> Expr a -> Expr b
|
| Take these two dummy types to represent things in the output language.
|
|  >data MyNum
|  >data MyBool
|
| Now it is very easy to create an Num instance for this language:
|
|  >primPlus :: Expr (MyNum -> MyNum -> MyNum)
|  >primPlus = Prim "prim+"
|
|  >instance Num (Epxr MyNum) where
|  >  a + b = primPlus `App` a `App` b
|  >  fromInteger = Prim . show
|  >  ...
|
| Which allows you to create very beautiful expression for your language
| embedded inside Haskell. The Haskell expression `10 * 5 + 2' produces
| a nice and well typed expression in your embedded domain.
|
| But unfortunately, not everyone in the Prelude is as tolerant as the
| Num instance. Take the Eq and the Ord type classes for example, they
| require you to deliver real Haskell `Bool's. This makes it impossible
| make your DSL an instance of these two, because there are no `Bool's
| only `Expr Bool's.
|
| Which brings me to the point that, for the sake of embedding other
| languages, Haskell's Prelude (or an alternative) can greatly benefit
| from (at least) a Boolean type class like this:
|
| class Boolean a where
|    ifthenelse :: a -> b -> b -> b         -- Not sure about this
| representation.
|    ...
|
| And one instance:
|
|  >instance Boolean (Expr MyBool) where
|  >  ifthenelse c a b = Prim "if-then-else" `App` c `App` a `App` b
|
| Now we can change (for example) the Eq type class to this:
|
|  >class Eq a where
|  >  (==) :: Boolean b => a -> a -> b
|  >  (/=) :: Boolean b => a -> a -> b
|
| For which we can give an implementation for our domain:
|
|  >primEq :: Epxr (a -> a -> MyBool)
|  >primEq = Prim "=="
|
|  >instance Eq (Expr a) where
|  >  a == b = primEq `App` a `App` b
|
| And now we get all functionality from the Prelude that is based on Eq
| (like not, &&, ||, etc) for free in our domain specific language! Off
| course there are many, many more examples of things from the standard
| libraries that can be generalised in order to serve reuse in EDSLs.
|
| Anyone already working on such a generalized Prelude? I can imagine
| much more domains can benefit from this than my example above. Any
| interesting thoughts or pointers related to this subject?
|
| Gr,
|
| --
| Sebastiaan Visser
|
| _______________________________________________
| 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