Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Is there an example, in any language, showing how you would represent this at the type level? I can’t see how you would do it.


In Elm (and many other languages, I assume, I'm just most familiar with Elm) there's a pattern called "opaque data type". [0] You make a file that contains the type and its constructor but you don't export the constructor. You only export the getter and setter methods. This ensures that if you properly police the methods of that one short file, everywhere else in your program that the type is used is guaranteed by the type system to have a number between zero and one.

-- BetweenZeroAndOne.elm

module BetweenZeroAndOne exposing (get, set)

type BetweenZeroAndOne = BetweenZeroAndOne Float

set : Float -> BetweenZeroAndOne set value = BetweenZeroAndOne (Basics.clamp 0.0 1.0 value)

get : BetweenZeroAndOne -> Float get (BetweenZeroAndOne value) = value

[0] https://en.wikipedia.org/wiki/Opaque_data_type#:~:text=In%20....


You would just make the constructor return a possible error if it's not in range, or maybe some specialty constructors that may clamp it into range for you so they always succeed.

It's the same question of, how can you convert a string to a Regexp type if not all strings are valid Regexps?


Right, so there's no way to do this:

> In other words, the parameter should not be a float, but a more constrained type that allows floats only in [0,1]

It's a value check, not a type check.


Typescript:

    type NormalisedFloat = number
Admittedly it doesn't add any actual value checking, but it does convey the information when you look at the parameter definition.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: