Skip to content

Instantly share code, notes, and snippets.

@JoelQ
Last active June 2, 2017 19:56
Show Gist options
  • Save JoelQ/69c76250753247ee2cbc465ff2ee322a to your computer and use it in GitHub Desktop.
Save JoelQ/69c76250753247ee2cbc465ff2ee322a to your computer and use it in GitHub Desktop.
Script to generate domain-specific Elm types wrapping primitives (see https://robots.thoughtbot.com/lessons-learned-avoiding-primitives-in-elm for why this is a good idea)

Script to generate domain-specific Elm types wrapping primitives (see https://robots.thoughtbot.com/lessons-learned-avoiding-primitives-in-elm for why this is a good idea)

Use looks like:

% ./create_newtype Email String > email.elm
module Email exposing (Email, fromString, toString, map, map2)

type Email = Email String

fromString : String -> Email
fromString x =
  Email x

toString : Email -> String
toString (Email x) =
  x

map : (String -> String) -> Email -> Email
map f (Email x) =
  Email (f x)

map2 : (String -> String -> String) -> Email -> Email -> Email
map2 f (Email x) (Email y) =
  Email (f x y)
#!/usr/bin/env ruby
newtype = ARGV[0]
wrapped_type = ARGV[1]
text = <<-TXT
module #{newtype} exposing (#{newtype}, from#{wrapped_type}, to#{wrapped_type}, map, map2)
type #{newtype} = #{newtype} #{wrapped_type}
from#{wrapped_type} : #{wrapped_type} -> #{newtype}
from#{wrapped_type} x =
#{newtype} x
to#{wrapped_type} : #{newtype} -> #{wrapped_type}
to#{wrapped_type} (#{newtype} x) =
x
map : (#{wrapped_type} -> #{wrapped_type}) -> #{newtype} -> #{newtype}
map f (#{newtype} x) =
#{newtype} (f x)
map2 : (#{wrapped_type} -> #{wrapped_type} -> #{wrapped_type}) -> #{newtype} -> #{newtype} -> #{newtype}
map2 f (#{newtype} x) (#{newtype} y) =
#{newtype} (f x y)
TXT
puts text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment