Hi Daniil,<br><br>By "embedded" DSL, we usually mean identifying meta-language (Haskell)
expressions with object language (DSL) expressions, rather than having
an "Exp" data type. Then you just use meta-language variables as
object-language variables. The new data types you introduce are then
domain-oriented rather than language-oriented. Is there a reason that
this kind of "embedded" approach doesn't work for you?<br>
<br>
Cheers, - Conal<br><br><div><span class="gmail_quote">On 6/7/07, <b class="gmail_sendername">Daniil Elovkov</b> <<a href="mailto:daniil.elovkov@googlemail.com">daniil.elovkov@googlemail.com</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Hello folks<br><br>Haskell is considered good for embedded DSLs. I'm trying to implement<br>some simple EDSL in a typeful manner and having a problem with looking<br>up variable values.<br><br>I've got an Expression GADT, which admits variables. The problem is
<br>with writing compute function which will lookup variable values in a<br>type-safe manner.<br><br>The exp. data type is like this<br><br>data Exp a where<br> Const a :: Val a -> Exp a<br> Var :: a -> String -> Exp a -- where the first comp. isn't
<br>used,only for type info.<br> ....<br><br>So, obviously, I have to perform lookups in some 'scope' to compute<br>the expression. By scope I mean the list of (name,value) pairs.<br><br>How do I represent the scope? Well, I haven't gone that far as to
<br>encode statically the information about the type of every variable in<br>scope. Instead, I used existentials to hide their types and put'em all<br>in a list.<br><br>For that purpose I introduced pack/unpack.<br><br>
-- value with dynamic type annotation<br>-- m here and below can be Val, Exp, etc.<br>-- to represent Val Int, Exp Int, etc.<br>data Type m = TInt (m Int) | TString (m String) | TDouble (m Double)<br><br>class Typed a where
<br> typ :: m a -> Type m<br><br>instance Typed Int where typ x = TInt x<br>instance Typed String where typ x = TString x<br>instance Typed Double where typ x = TDouble x<br><br>data Opaque m = forall a. (Typed a) => Opaque (m a)
<br><br>-- extract to an annotated representation<br>extract :: Opaque m -> Type m<br>extract (Opaque a) = typ a<br><br>How would you suggest, I write compute function?<br><br>My try was<br><br>compute :: Scope -> Exp t -> Val t
<br>compute scope (Const x) = x -- trivial<br><br>compute scope (Var t name) = -- intereseting part<br> let opq = lookup name scope<br> val = case opq of<br> Nothing -> error "not in scope"
<br> Just opq -> extract opq<br> expType = aux t<br> in case val `matches` expType of -- I'd like to make some 'matches' func.<br> Nothing -> error "type error" -- which would either produce an error
<br> Just v -> v -- or return the value, based on run-time tags<br><br>matches :: Typed m -> Typed m -> Maybe (m a)<br> BUT of course this type is bad, there's no 'a' in the left side<br>
matches (TInt x) (TInt _) = Just x<br>matches (TString x) (TString _) = Just x<br>matches (TDouble x) (TDouble _) = Just x<br>matches _ _ = Nothing<br><br>So, clearly the problem is in that Type m has no evidence of a, which
<br>was its very purpose. Ok, so I made<br><br>data FType m a where<br> FInt :: m Int -> FType m Int<br> FString :: m String -> FType m String<br> FDouble :: m Double -> Aux m a<br><br>class Typed a where
<br> typ :: m a -> Type m -- as before<br> ftyp :: m a -> FType m a -- new one<br><br>and again obvious instance<br>instance Typed Int where ftyp x = FInt x<br>...<br><br>And of course, I'd like to get that information somehow
<br> extract2 (Opaque a) = ftyp a<br>I rewrote 'matches' accordingly but the problem is already in the type<br>of extract2<br><br>its type Opaque m -> (forall a. (Typed a) => m a)<br>is not good to ghc, less polymorphic than expected
<br><br>So, in principle it must be doable, since opaque data retains its<br>dictionary, and by that I can get a dynamic tag, say FInt x, where x<br>is proved to be Int.<br><br>What would you suggest?<br><br>Thank you<br>
_______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br><a href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe
</a><br></blockquote></div><br>