Здесь есть ряд проблем.
Прежде всего, результатом понимания списка является список, поэтому вы вызываете Data.Vector.map
для списка, который не будет работать. И x
внутри понимания - это Vector
, что является еще одним несоответствием типов. Либо используйте список вместо вектора (вместе с Prelude.map
), либо преобразуйте список в Vector
(в этом случае вы не можете использовать понимание списка).
Во-вторых, игнорируя проблему списка / Vector
, [i !! 2 | i <- x]
даст вам список, содержащий только элементы в позиции 2 из каждого подсписка. Используя ваш пример, понимание даст ["12", "34"]
. Затем, когда вы отобразите read
поверх него, вы получите [12, 34]
, а не результат, для которого вы стреляете.
Наконец, вывод, который вы хотите увидеть, недопустим для списков или для Vectors
в Haskell. Контейнеры обоих типов должны быть однородными, то есть они не могут содержать значения более одного типа. [Int]
не может содержать String
с, а [String]
не может содержать Int
с, но ваш желаемый вывод содержит оба. Существуют способы обойти это, используя экзистенциальные типы, но есть вероятность, что есть лучшее решение для вашей основной проблемы, чем пытаться создавать гетерогенные коллекции.
Редактировать: Вы отредактировали последнюю часть своего поста, чтобы использовать кортежи, поэтому приведенный выше абзац больше не применяется. Первые две упомянутые проблемы все еще существуют.
Если вы начнете со списка из 4-х кортежей ([(String, String, String, String)]
), вы можете получить то, что хотите, вот так:
> let x = [("a", "b", "12", "d"), ("e", "f", "34", "g")]
> map (\(a, b, c, d) -> (a, b, read c :: Int, d)) x
[("a", "b", 12, "d"), ("e", "f", 34, "g")]