Authorize complete patterns as function args.

This is mainly a syntactic trick/sugar, but it's been pretty annoying
  to me for a while that we can't simply pattern-match/destructure
  single-variant constructors directly from the args list. A classic
  example is when writing property tests:

  ```ak
  test foo(params via both(bytearray(), int())) {
    let (bytes, ix) = params
    ...
  }
  ```

  Now can be replaced simply with:

  ```
  test foo((bytes, ix) via both(bytearray(), int())) {
    ...
  }
  ```

  If feels natural, especially coming from the JavaScript, Haskell or
  Rust worlds and is mostly convenient. Behind the scene, the compiler
  does nothing more than re-writing the AST as the first form, with
  pre-generated arg names. Then, we fully rely on the existing
  type-checking capabilities and thus, works in a seamless way as if we
  were just pattern matching inline.
This commit is contained in:
KtorZ
2024-06-07 15:23:33 +02:00
parent b6da42baf2
commit 858dfccc82
23 changed files with 944 additions and 68 deletions

View File

@@ -507,10 +507,8 @@ impl Prng {
fn as_prng(cst: &PlutusData) -> Prng {
if let PlutusData::Constr(Constr { tag, fields, .. }) = cst {
if *tag == 121 + Prng::SEEDED {
if let [
PlutusData::BoundedBytes(bytes),
PlutusData::BoundedBytes(choices),
] = &fields[..]
if let [PlutusData::BoundedBytes(bytes), PlutusData::BoundedBytes(choices)] =
&fields[..]
{
return Prng::Seeded {
choices: choices.to_vec(),
@@ -1089,11 +1087,9 @@ impl TryFrom<TypedExpr> for Assertion<TypedExpr> {
final_else,
..
} => {
if let [
IfBranch {
condition, body, ..
},
] = &branches[..]
if let [IfBranch {
condition, body, ..
}] = &branches[..]
{
let then_is_true = match body {
TypedExpr::Var {
@@ -1512,14 +1508,13 @@ mod test {
}
"#});
assert!(
prop.run::<()>(
assert!(prop
.run::<()>(
42,
PropertyTest::DEFAULT_MAX_SUCCESS,
&PlutusVersion::default()
)
.is_success()
);
.is_success());
}
#[test]