| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Stratosphere
Contents
Description
This is a library for creating AWS CloudFormation templates.
CloudFormation is a system that creates AWS resources from declarative templates. One common criticism of CloudFormation is its use of JSON as the template specification language. Once you have a large number of templates, possibly including cross-references among themselves, raw JSON templates become unwieldy, and it becomes harder to confidently modify them. Stratosphere alleviates this issue by providing an Embedded Domain Specific Language (EDSL) to construct templates.
Synopsis
- module Stratosphere.Check
- module Stratosphere.NamedItem
- module Stratosphere.Output
- module Stratosphere.Parameter
- module Stratosphere.Property
- module Stratosphere.Resource
- module Stratosphere.ResourceProperties
- module Stratosphere.Tag
- module Stratosphere.Template
- module Stratosphere.Value
- ($) :: (a -> b) -> a -> b
- data Text
- (.) :: (b -> c) -> (a -> b) -> a -> c
- (&) :: a -> (a -> b) -> b
- awsAccountId :: Value Text
- awsNoValue :: Value Text
- awsRegion :: Value Text
- awsStackId :: Value Text
- awsStackName :: Value Text
Introduction
The core datatype of stratosphere is the Template, which corresponds to a
single CloudFormation template document. Users construct a template in a
type-safe way using simple data types. The following example creates a
template containing a single EC2 instance with a key pair passed in as a
parameter:
instanceTemplate :: Template instanceTemplate = template [ resource EC2Instance ( EC2InstanceProperties $ ec2Instance & eciImageId ?~ "ami-22111148" & eciKeyName ?~ (Ref KeyName) ) & resourceDeletionPolicy ?~ Retain ] & templateDescription ?~ "Sample template" & templateParameters ?~ [ parameter KeyName "AWS::EC2::KeyPair::KeyName" & parameterDescription ?~ "Name of an existing EC2 KeyPair to enable SSH access to the instance" & parameterConstraintDescription ?~ "Must be the name of an existing EC2 KeyPair." ]
Usage
The types in stratosphere attempt to map exactly to CloudFormation template
components. For example, a template requires a set of Resources, and
optionally accepts a Description, Parameters, etc. For each component of a
template, there is usually a set of required arguments, and a (usually
large) number of optional arguments. Each record type has a corresponding
constructor function that has the required parameters as arguments.
For example, since a Template requires a set of Resources, the template
constructor has Resources as an argument. Then, you can fill in the
Maybe parameters using record updates.
Once a Template is created, you can either use Aeson's encode function, or
use our encodeTemplate function (based on aeson-pretty) to produce a JSON
ByteString. From there, you can use your favorite tool to interact with
CloudFormation using the template.
module Stratosphere.Check
module Stratosphere.NamedItem
module Stratosphere.Output
module Stratosphere.Parameter
module Stratosphere.Property
module Stratosphere.Resource
module Stratosphere.Tag
module Stratosphere.Template
module Stratosphere.Value
($) :: (a -> b) -> a -> b infixr 0 #
is the function application operator.($)
Applying to a function ($)f and an argument x gives the same result as applying f to x directly. The definition is akin to this:
($) :: (a -> b) -> a -> b ($) f x = f x
This is specialized from ida -> a to (a -> b) -> (a -> b) which by the associativity of (->)
is the same as (a -> b) -> a -> b.
On the face of it, this may appear pointless! But it's actually one of the most useful and important operators in Haskell.
The order of operations is very different between ($) and normal function application. Normal function application has precedence 10 - higher than any operator - and associates to the left. So these two definitions are equivalent:
expr = min 5 1 + 5 expr = ((min 5) 1) + 5
($) has precedence 0 (the lowest) and associates to the right, so these are equivalent:
expr = min 5 $ 1 + 5 expr = (min 5) (1 + 5)
Examples
A common use cases of ($) is to avoid parentheses in complex expressions.
For example, instead of using nested parentheses in the following Haskell function:
-- | Sum numbers in a string: strSum "100 5 -7" == 98 strSum ::String->IntstrSum s =sum(mapMaybereadMaybe(wordss))
we can deploy the function application operator:
-- | Sum numbers in a string: strSum "100 5 -7" == 98 strSum ::String->IntstrSum s =sum$mapMaybereadMaybe$wordss
($) is also used as a section (a partially applied operator), in order to indicate that we wish to apply some yet-unspecified function to a given value. For example, to apply the argument 5 to a list of functions:
applyFive :: [Int] applyFive = map ($ 5) [(+1), (2^)] >>> [6, 32]
Technical Remark (Representation Polymorphism)
($) is fully representation-polymorphic. This allows it to also be used with arguments of unlifted and even unboxed kinds, such as unboxed integers:
fastMod :: Int -> Int -> Int fastMod (I# x) (I# m) = I# $ remInt# x m
A space efficient, packed, unboxed Unicode text type.
Instances
(.) :: (b -> c) -> (a -> b) -> a -> c infixr 9 #
Right to left function composition.
(f . g) x = f (g x)
f . id = f = id . f
Examples
>>>map ((*2) . length) [[], [0, 1, 2], [0]][0,6,2]
>>>foldr (.) id [(+1), (*3), (^3)] 225
>>>let (...) = (.).(.) in ((*2)...(+)) 5 1030
(&) :: a -> (a -> b) -> b infixl 1 #
& is a reverse application operator. This provides notational
convenience. Its precedence is one higher than that of the forward
application operator $, which allows & to be nested in $.
This is a version of , where flip idid is specialized from a -> a to (a -> b) -> (a -> b)
which by the associativity of (->) is (a -> b) -> a -> b.
flipping this yields a -> (a -> b) -> b which is the type signature of &
Examples
>>>5 & (+1) & show"6"
>>>sqrt $ [1 / n^2 | n <- [1..1000]] & sum & (*6)3.1406380562059946
Since: base-4.8.0.0
awsAccountId :: Value Text Source #
awsNoValue :: Value Text Source #
awsStackId :: Value Text Source #