Any way to eliminate hlist?

Calling elim(hlist) and elim(tail) does not provide you any dispatch. Out of 3 overloads of elim() compiler attempts to pick one at compilation time, and will always use it regardless of value of T. Looks like compiler attempts to use the last one, which expects HList<End>.

If I'm not mistaken, what you are trying to achieve is called Generalized abstract data types (GADTs)?, which currently not supported in Swift. But you can emulate them using protocols and visitor pattern:

protocol HList {
    func accept<V: HListVisitor>(_ visitor: V) -> V.Result
}

protocol HListVisitor {
    associatedtype Result
    func visitCons<Head, Tail: HList>(head: Head, tail: Tail) -> Result
    func visitEnd() -> Result
}

struct End: HList {
    func accept<V: HListVisitor>(_ visitor: V) -> V.Result {
        return visitor.visitEnd()
    }
}

struct Cons<Head, Tail: HList>: HList {
    var head: Head
    var tail: Tail

   func accept<V: HListVisitor>(_ visitor: V) -> V.Result {
        return visitor.visitCons(head: head, tail: tail)
    }
}

func elimHList<T: HList>(_ hlist: T) -> Double? {
    struct DoubleEliminator: HListVisitor {
        func visitCons<Head, Tail: HList>(head: Head, tail: Tail) -> Double? {
            if let doubleHead = head as? Double {
                return doubleHead
            }
           return tail.accept(self)
        }
        func visitEnd() -> Double? {
            return nil
        }
    }
    return hlist.accept(DoubleEliminator())
}