anchor.diff:          let delays = [| 0..8 |] |> Array.map calcDelay
   
           (fun retries -> delays.[min retries 8])
  +
  +    let inline csv (arr : 'a[]) = String.Join(",", arr)
   
       let deserialize<'T> = 
           let serializer = new DataContractJsonSerializer(typeof<'T>)
  
positive.code:     
      /// Returns the shards that are part of the stream
      let getShards (kinesis : IAmazonKinesis) (StreamName streamName) =
          async {
              let req = new DescribeStreamRequest(StreamName = streamName)
              let! res = kinesis.DescribeStreamAsync(req) |> Async.AwaitTask        
                 
              logDebug "Stream [{0}] has [{1}] shards: [{2}]"
                       [| res.StreamDescription.StreamName
                          res.StreamDescription.Shards.Count
                          String.Join(",", res.StreamDescription.Shards |> Seq.map(fun shard -> shard.ShardId)) |]
  
              return res.StreamDescription.Shards
          }
  
      /// Returns the shard iterator for the specified shard in the stream
      let getShardIterator (kinesis : IAmazonKinesis) 
  
negative.code:             let! _ = dynamoDB.UpdateItemAsync(req) |> Async.AwaitTask
  
              logDebug "Issued handover request for shard [{0}] from worker [{1}] to worker [{2}] in table [{3}], expiring at [{4}]" 
                       [| shardId; fromWorkerId; toWorkerId; tableName; expiry |]
          }
          |> Async.Catch
  
  