Did you mean "Boolrepr" instead of "Seqrepr"?

There are various tradeoffs here for the design of an embedded abstract language repreesntation. You can use fewer, more general types (e.g. a general type of structured expressions), or you can proliferate types and have Seqrepr, Boolrepr, Intrepr etc. e.g.

type Seqrepr = ...

and Boolrepr = ... // your GreaterThen case would go here.

The merits of the different approaches willl depend a bit on what you're going to be doing. Since it sounds like optimization of a specific language is your aim, the second approach may work well for you.

Kind regards

don

By on 4/23/2009 3:27 PM ()

Hi Don,

Thanks for your reply. My post seems to have been somewhat mangled; the '<' and '>' enclosing the type all vanished! (I will use an alternate syntax) It was meant to read as:

1
2
3
4
5
6
7
8
9
10
type 'a Seqrepr = 
    | Seqrepr of 'a
    | Named of string*'a
    | Plus of ('a Seqrepr)*('a Seqrepr)
    | Minus of ('a Seqrepr)*('a Seqrepr)
    | Mult of ('a Seqrepr)*('a Seqrepr)
    | Divide of ('a Seqrepr)*('a Seqrepr)
    | Max of ('a Seqrepr)*('a Seqrepr)
    | Min of ('a Seqrepr)*('a Seqrepr)
    | Conditional of ('a Seqrepr)*('a Seqrepr)*(bool Seqrepr)

As you have suggested, it would certainly be an option to define a range of types for each underlying type (i.e. float,int,datetime..). The problem with this approach is that I wish to use AST's of Seqexpr<'a> within another type; so, for instance:

1
2
3
4
5
6
type Inst = 
    | Zero    
    | One
    | And of Inst*Inst
    | When  of Inst*(bool Seqexpr)
    | Scale of Inst*(float Seqrepr)

Using this type, I wish to construct generic representations to represent certain actions on the undelying Seqrepr, e.g

1
2
let example (s1: 'a Seqexpr) s2 = 
       When (Scale One s1) (GreaterThan s1 s2)

This would not require the caller provide an argument for the (bool Seqexpr) resulting from the 'GreaterThan s1 s2'. If I were to define different types (e.g. Floatrepr, Datetimerepr,..) and then have a Boolrepr as:

1
2
3
4
type Boolrepr = 
    | FloatGreaterThan of (float Seqrepr)*(float Seqrepr)
    | DateGreaterThan of (DateTime Seqrepr)*(DatTime Seqrepr)
    | etc..

I could no longer allow the arguments of my example function to be generic.

It is also an aim my make the DSL familiar to a user; my fear is it would become rather cumbersome with a proliferation of types.

Any thoughts or suggestions would be most welcome.

Best regards,

Michael

By on 4/24/2009 1:43 AM ()

I came across a paper named 'Fun with phantom types' by Ralf Hinze which suggests a 'mild' extension to Haskell to allow for this kind of behavior. The example Haskell code given is:

data Term t = Zero with t = Int
| Succ (Term Int) with t = Int
| Pred (Term Int) with t = Int
| IsZero (Term Int) with t = Bool
| If (Term bool) (Term a) (Term a) with t = a

I also understand this is implement in Haskell as Generalized Algebraic Data Types.

Is there any way to replicate this in F#?

Regards,

Michael

By on 4/27/2009 2:37 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper