Hi,
Let me show you why I reached that conclusion through a simple example. Imagine that, for some reason, we need to implement a DSL which is required to use vectors. Furthermore, we would like to make transformations/sanity checks at compile time. To keep things simple, the vector is internally represented as a list: newtype Vec a = MkVec [a] -- Note that MkVec would be hidden to the end user. Using Template Haskell, we can easily create a constructor function which fulfils all the requirements. vector :: Lift a => [a] -> QExp vector xs = do sanityCheck xs [| MkVec xs |] where sanityCheck = undefined -- not specified Using "vector" is simple: $(vector [1,2,3,4,5]) OK, fair enough. However, pattern matching is lost and it would be nicer to be able to to build vector literals using a syntax different to lists. For example, using less-than and more-than symbols to enclose the vector elements: <1,2,3,4,5> We would also like to do some pattern matching: <> -- empty vector x <xs> -- head and tail of the vector Using a quasiquoter all the above is is possible. In the case of Int vectors, supposing name our quasiquoter v we could do things like. [$v|<1,2,3,4,5,6>|] head :: Vector Int -> Int f v = case v of [$v|<>|] -> error "empty" [$v|x<xs>|] -> x Looks nice, but we lose polymorphism! It is imposible to make v work with any instance of Read! Here is a possible implementation: -- parse a list enclosed with lower-than and greater-than characters parseLTGT :: Read a => String -> [a] parseLTGT = undefined -- code ommited v = QuasiQuoter vExp vPat -- In the case of Ints it is simple vExp :: String -> Q Exp vExp str = do let xs = (readLTGT str) :: [Int] sanityCheck xs [| MkVec xs |] Unfortunately, we cannot implement vExpr in the general case. Removing the explicit signature of readLTGT would lead to ambiguous-type-variable errors. Maybe things would be different if TH's AST wasn't untyped (i.e. vExpr :: String -> Q (Exp a)) I'm not sure if it is feasible, though. I would love to be proven wrong and read about a workaround/solution. Any suggestions? Cheers, Fons _______________________________________________ template-haskell mailing list [hidden email] http://www.haskell.org/mailman/listinfo/template-haskell |
On Wed, Feb 20, 2008 at 8:22 AM, Alfonso Acosta
<[hidden email]> wrote: > Maybe things would be different if TH's AST wasn't untyped (i.e. vExpr > :: String -> Q (Exp a)) I'm not sure if it is feasible, though. I meant vExp :: String -> Q (Exp (Vec a)) Sorry for the typo _______________________________________________ template-haskell mailing list [hidden email] http://www.haskell.org/mailman/listinfo/template-haskell |
In reply to this post by Bugzilla from alfonso.acosta@gmail.com
On Wed, Feb 20, 2008 at 9:12 AM, Geoffrey Mainland
<[hidden email]> wrote: > On Wed, Feb 20, 2008 at 08:22:18AM +0100, Alfonso Acosta wrote: > > Hi, > > > > Let me show you why I reached that conclusion through a simple example. > > I can't help but feel I've missed some context :) Well, I'm probably bad at providing simplified examples ;). The real purpose of using quasiquoters is to help implementing fixed sized vectors (numerically parameterized lists using type-level numerals). See http://www.haskell.org/pipermail/haskell-cafe/2008-February/039801.html for details. > > Using "vector" is simple: > > > > $(vector [1,2,3,4,5]) > > Well, not so simple actually, as you'll get an "ambiguous type variable" > error unless you add a type signature. For instance: > > $(vector [1::Int,2,3,4,5]) True, I forgot to include the signature. However, even if a signature is required, vector can still be used to build vectors of any type, whereas that is not the case when using quasiquoters. > The real problem is that you can't splice in a polymorphic > variable. Witness: > > v = QuasiQuoter (fst . vExp) vPat > > vExp :: Read a => String -> (Q Exp, a) > vExp str = do let xs = (parseLTGT str) :: [a] > sanityCheck xs > ([| MkVec xs |], undefined) > Yes, I know. I thought it would maybe be possible if TH had a typed AST. _______________________________________________ template-haskell mailing list [hidden email] http://www.haskell.org/mailman/listinfo/template-haskell |
Free forum by Nabble | Edit this page |