Is there a language with constrainable types?

后端 未结 8 1003
北海茫月
北海茫月 2020-12-09 15:59

Is there a typed programming language where I can constrain types like the following two examples?

  1. A Probability is a floating point number with minimum val

相关标签:
8条回答
  • 2020-12-09 16:53

    Perl6 has a notion of "type subsets" which can add arbitrary conditions to create a "sub type."

    For your question specifically:

    subset Probability of Real where 0 .. 1;
    

    and

    role DPD[::T] {
      has Map[T, Probability] $.map
        where [+](.values) == 1; # calls `.values` on Map
    }
    

    (note: in current implementations, the "where" part is checked at run-time, but since "real types" are checked at compile-time (that includes your classes), and since there are pure annotations (is pure) inside the std (which is mostly perl6) (those are also on operators like *, etc), it's only a matter of effort put into it (and it shouldn't be much more).

    More generally:

    # (%% is the "divisible by", which we can negate, becoming "!%%")
    subset Even of Int where * %% 2; # * creates a closure around its expression
    subset Odd of Int where -> $n { $n !%% 2 } # using a real "closure" ("pointy block")
    

    Then you can check if a number matches with the Smart Matching operator ~~:

    say 4 ~~ Even; # True
    say 4 ~~ Odd; # False
    say 5 ~~ Odd; # True
    

    And, thanks to multi subs (or multi whatever, really – multi methods or others), we can dispatch based on that:

    multi say-parity(Odd $n) { say "Number $n is odd" }
    multi say-parity(Even) { say "This number is even" } # we don't name the argument, we just put its type
    #Also, the last semicolon in a block is optional
    
    0 讨论(0)
  • 2020-12-09 16:55

    The Whiley language supports something very much like what you are saying. For example:

    type natural is (int x) where x >= 0
    type probability is (real x) where 0.0 <= x && x <= 1.0
    

    These types can also be implemented as pre-/post-conditions like so:

    function abs(int x) => (int r)
    ensures r >= 0:
        //
        if x >= 0:
            return x
        else:
            return -x
    

    The language is very expressive. These invariants and pre-/post-conditions are verified statically using an SMT solver. This handles examples like the above very well, but currently struggles with more complex examples involving arrays and loop invariants.

    0 讨论(0)
提交回复
热议问题