sizeOf' f (TECase ty expr cases)                    = do
  env <- ask
  exprSize <- sizeOf' f expr
  let exprType = getTypeAnno expr
  let isRecType = (== exprType)
  variant <- lift $ getVariantType exprType
  casesWSize <- forM cases $ \(id, (vars, caseExpr)) -> do
                 caseTypes <- case lookup id variant of
                                Just ts -> return ts
                                Nothing  ->
                                  throwError $ SizeError "Incompatible pattern"
                 let annoVars = zip vars caseTypes
                 let argEnv = map (\(v, t) -> if isRecType t
                                              then (v, DataPos $ D exprSize)
                                              else (v, DataPos $ Var v)) annoVars
                 let isBaseCase = all (\(v,t) -> not $ isRecType t) annoVars
                 if isBaseCase
                  then do let newF = updateControlPoint f exprSize (const Min)
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos Min)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          baseCaseSize <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, baseCaseSize)
                  else do let newF = updateControlPoint f exprSize NotMin
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos $ NotMin size)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          size <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, size)
  let caseSizes = map snd casesWSize
  let maxSize = if null caseSizes then Unknown else foldr1 max caseSizes -- Gør det mest konservative.
  case lookup expr (hints env) of
    Just hint ->
      case find (\c -> fst c == hint) casesWSize of
        Just (_, size) -> return size
        Nothing        -> return maxSize
    Nothing -> return maxSize

sizeOf' f (TECase ty expr cases)                    = do
  env <- ask
  exprSize <- sizeOf' f expr
  let exprType = getTypeAnno expr
  let isRecType = (== exprType)
  variant <- lift $ getVariantType exprType
  casesWSize <- forM cases $ \(id, (vars, caseExpr)) -> do
                 caseTypes <- case lookup id variant of
                                Just ts -> return ts
                                Nothing  ->
                                  throwError $ SizeError "Incompatible pattern"
                 let annoVars = zip vars caseTypes
                 let argEnv = map (\(v, t) -> if isRecType t
                                              then (v, DataPos $ D exprSize)
                                              else (v, DataPos $ Var v)) annoVars
                 let isBaseCase = all (\(v,t) -> not $ isRecType t) annoVars
                 if isBaseCase
                  then do let newF = updateControlPoint f exprSize (const Min)
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos Min)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          baseCaseSize <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, baseCaseSize)
                  else do let newF = updateControlPoint f exprSize NotMin
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos $ NotMin size)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          size <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, size)
  let caseSizes = map snd casesWSize
  let maxSize = if null caseSizes then Unknown else foldr1 max caseSizes -- Gør det mest konservative.
  case lookup expr (hints env) of
    Just hint ->
      case find (\c -> fst c == hint) casesWSize of
        Just (_, size) -> return size
        Nothing        -> return maxSize
    Nothing -> return maxSize
sizeOf' f (TECase ty expr cases)                    = do
  env <- ask
  exprSize <- sizeOf' f expr
  let exprType = getTypeAnno expr
  let isRecType = (== exprType)
  variant <- lift $ getVariantType exprType
  casesWSize <- forM cases $ \(id, (vars, caseExpr)) -> do
                 caseTypes <- case lookup id variant of
                                Just ts -> return ts
                                Nothing  ->
                                  throwError $ SizeError "Incompatible pattern"
                 let annoVars = zip vars caseTypes
                 let argEnv = map (\(v, t) -> if isRecType t
                                              then (v, DataPos $ D exprSize)
                                              else (v, DataPos $ Var v)) annoVars
                 let isBaseCase = all (\(v,t) -> not $ isRecType t) annoVars
                 if isBaseCase
                  then do let newF = updateControlPoint f exprSize (const Min)
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos Min)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          baseCaseSize <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, baseCaseSize)
                  else do let newF = updateControlPoint f exprSize NotMin
                          let caseEnv = addData argEnv . addControlPoint newF .
                                        addData (map (\(name, DataPos size) -> (name, DataPos $ NotMin size)) $ filter (\(_, DataPos size) -> size == exprSize) (dataPositions env))
                          size <- local caseEnv $ sizeOf' newF caseExpr
                          return (id, size)
  let caseSizes = map snd casesWSize
  let maxSize = if null caseSizes then Unknown else foldr1 max caseSizes -- Gør det mest konservative.
  case lookup expr (hints env) of
    Just hint ->
      case find (\c -> fst c == hint) casesWSize of
        Just (_, size) -> return size
        Nothing        -> return maxSize
    Nothing -> return maxSize