Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Last active August 29, 2015 14:12
Show Gist options
  • Save TheSeamau5/9f8c7857a8958e1d79c5 to your computer and use it in GitHub Desktop.
Save TheSeamau5/9f8c7857a8958e1d79c5 to your computer and use it in GitHub Desktop.
Proposal for meta annotations in Elm
-- REQUIRE META ANNOTATION:
-- The require meta-annotation will force the input record type vector to have a z field
require {z : Float} from vector
moveZ : Float -> vector -> vector
moveZ z v = { v | z <- v.z + z }
-- The top code is equivalent to
moveZ : Float -> { a | z : Float } -> { a | z : Float }
moveZ z v = { v | z <- v.z + z }
------------------
-- PROHIBIT META ANNOTATION
-- The prohibit meta-annotation will ban any input record type with an existing z field
prohibit {z : Float} from vector2d
add3dComponent : vector2d -> vector3d
add3dComponent v = { v | z = 0 }
-- This has no current equivalent in Elm
-------------------
-- OPTIONAL META ANNOTATION
-- The optional meta-annotation will declare that a field is optional and as such
-- must be properly handled. Checking is made with a built-in "has" function.
optional {z : Float} from vector
add : vector -> vector -> vector
add p q =
if (has {z : Float} p)
then
{p | x <- p.x + q.x, y <- p.y + q.y, z <- p.z + q.z }
else
{p | x <- p.x + q.x, y <- p.y + q.y }
-- The above is not possible in Elm. The only way to achieve this
-- is by splitting it into two distinct functions
add2 : {a | x : Float, y : Float} -> {b | x : Float, y : Float} -> {a | x : Float, y : Float }
add2 p q = {p | x <- p.x + q.x, y <- p.y + q.y }
add3 : {a | x : Float, y : Float, z : Float} ->
{b | x : Float, y : Float, z : Float} ->
{a | x : Float, y : Float, z : Float}
add3 p q = {p | x <- p.x + q.x, y <- p.y + q.y, z <- p.z + q.z}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment