Enable Pattern Matching in Trait
Closed this issue · 0 comments
mlhaufe commented
Given the following definition and associated expression:
const Expr = Data({ Num: ['value'], Var: ['name'], Mul: ['left', 'right'] })
const e = Mul(Var('x'), Num(1))
How can e
be simplified to Var('x')
?
Currently here is the idiomatic approach:
// isNum and isVar ellided, but usually defined as well for completeness
const isNum = Trait(Expr, {
_: () => false,
Num: () => true
})
const simplify = Trait(Expr, {
_: (self) => self,
Mul: (self) => {
const {left, right} = self
if(isNum(left) && left.value == 1)
return simplify(right)
else if(isNum(right) && right.value == 1)
return simplify(left)
else if(isNum(left) && left.value == 0)
return Num(0)
else if(isNum(right) && right.value == 0)
return Num(0)
else
return self
}
})
const e2 = simplify(e)
With pattern matching (hypothetical syntax) the following may be possible:
const simplify = Trait(Expr, {
_: (self) => self,
Mul: [
[ {left: Num(1)}, ({right}) => right],
[ {right: Num(1)}, ({left}) => left ],
[ {left: Num(0)}, ({left}) => left ],
[ {right: Num(0)}, ({right}) => right]
]
})
Pattern syntax
const traitName = Trait(DataDecl, {
VariantName: (self, ...args) => {...},
VariantName: [
[pattern1, pattern2, ...patternN, (self, v2, ...vN) => {...}]
]
})
Pattern types
// Literals
1
false
'foo'
// wildcard
_
// variant instances
Nil
Cons(1, Nil)
Cons(pattern1, pattern2)
Cons(1, Cons(pattern, Nil)
// structural
{left: 3, right: Nil }
{left: pattern1, right: pattern2 }