getSpotPrices :: [Region] -> [Text] -> [InstanceType] -> IO [HawsSpotPrice]
getSpotPrices rs zs ts= do
    lgr <- newLogger Info stdout
    env <- newEnv Discover <&> set envLogger lgr
    now <- getCurrentTime
    let rs' = if rs == [] then [NorthVirginia] else rs
        ts' = if ts == [] then [R3_XLarge] else ts
        start_time = addUTCTime (-60 * 15) now
        query = describeSpotPriceHistory
          & dsphInstanceTypes       .~ ts'
          & dsphProductDescriptions .~ ["Linux/UNIX (Amazon VPC)"]
          & dsphStartTime           .~ (Just start_time)
          & dsphEndTime             .~ (Just now)

    pss <- sequenceA $  fmap (request env query) rs'
    let ps = mconcat pss

    return $ (List.sort . filterLatestPrices . filterByZone) ps
      where
        request :: Env -> DescribeSpotPriceHistory -> Region -> IO [HawsSpotPrice]
        request env query r = do
          resp <- (runResourceT . runAWST env . (within r). send) query
          return $ processResponse r resp

        processResponse:: Region -> DescribeSpotPriceHistoryResponse -> [HawsSpotPrice]
        processResponse r resp =
          fmap (fromAmazonka r) (resp ^. dsphrsSpotPriceHistory)

        filterByZone :: [HawsSpotPrice] -> [HawsSpotPrice]
        filterByZone ps | zs == [] = ps
                        | True     = List.filter
                                     (\s-> List.elem (zone s) zs)
                                     ps
getSpotPrices :: [Region] -> [Text] -> [InstanceType] -> IO [HawsSpotPrice]
getSpotPrices rs zs ts= do
    lgr <- newLogger Info stdout
    env <- newEnv Discover <&> set envLogger lgr
    now <- getCurrentTime
    let rs' = if rs == [] then [NorthVirginia] else rs
        ts' = if ts == [] then [R3_XLarge] else ts
        start_time = addUTCTime (-60 * 15) now
        query = describeSpotPriceHistory
          & dsphInstanceTypes       .~ ts'
          & dsphProductDescriptions .~ ["Linux/UNIX (Amazon VPC)"]
          & dsphStartTime           .~ (Just start_time)
          & dsphEndTime             .~ (Just now)

    pss <- sequenceA $  fmap (request env query) rs'
    let ps = mconcat pss

    return $ (List.sort . filterLatestPrices . filterByZone) ps
      where
        request :: Env -> DescribeSpotPriceHistory -> Region -> IO [HawsSpotPrice]
        request env query r = do
          resp <- (runResourceT . runAWST env . (within r). send) query
          return $ processResponse r resp

        processResponse:: Region -> DescribeSpotPriceHistoryResponse -> [HawsSpotPrice]
        processResponse r resp =
          fmap (fromAmazonka r) (resp ^. dsphrsSpotPriceHistory)

        filterByZone :: [HawsSpotPrice] -> [HawsSpotPrice]
        filterByZone ps | zs == [] = ps
                        | True     = List.filter
                                     (\s-> List.elem (zone s) zs)
                                     ps
getSpotPrices rs zs ts= do
    lgr <- newLogger Info stdout
    env <- newEnv Discover <&> set envLogger lgr
    now <- getCurrentTime
    let rs' = if rs == [] then [NorthVirginia] else rs
        ts' = if ts == [] then [R3_XLarge] else ts
        start_time = addUTCTime (-60 * 15) now
        query = describeSpotPriceHistory
          & dsphInstanceTypes       .~ ts'
          & dsphProductDescriptions .~ ["Linux/UNIX (Amazon VPC)"]
          & dsphStartTime           .~ (Just start_time)
          & dsphEndTime             .~ (Just now)

    pss <- sequenceA $  fmap (request env query) rs'
    let ps = mconcat pss

    return $ (List.sort . filterLatestPrices . filterByZone) ps
      where
        request :: Env -> DescribeSpotPriceHistory -> Region -> IO [HawsSpotPrice]
        request env query r = do
          resp <- (runResourceT . runAWST env . (within r). send) query
          return $ processResponse r resp

        processResponse:: Region -> DescribeSpotPriceHistoryResponse -> [HawsSpotPrice]
        processResponse r resp =
          fmap (fromAmazonka r) (resp ^. dsphrsSpotPriceHistory)

        filterByZone :: [HawsSpotPrice] -> [HawsSpotPrice]
        filterByZone ps | zs == [] = ps
                        | True     = List.filter
                                     (\s-> List.elem (zone s) zs)
                                     ps