Haskell выполнение fst на кортеж из 3 частей

У меня есть следующий кортеж Haskell:

       [("string",1,1)]

Мне нужно извлечь первый элемент этого, очевидно, используя "fst", не будет работать здесь, поскольку есть 3 компонента.

какой метод лучше всего использовать? sel ?

5 ответов


вы можете просто ввести свою собственную функцию (мы будем использовать сопоставление шаблонов) для этого:

fst3 :: (a, b, c) -> a
fst3 (x, _, _) = x

и вы используете его как:

fst3 ("string", 1, 1)

sel может использоваться следующим образом:

$ cabal install tuple
$ ghci
>>> :m +Data.Tuple.Select
>>> sel1 ("string",1,1)
"string"

он работает как любая другая функция с map

>>> map sel1 [("One",1,0),("Two",2,0),("Three",3,0)]
["One","Two","Three"]

основным преимуществом является то, что он работает на крупную кортежа!--8-->

>>> sel1 ("string",1,1,1)
"string"

а также стандартный кортеж

>>> sel1 ("string",1)
"string"

следовательно, нет необходимости обрабатывать их отдельно.


еще несколько примеров:

>>> map sel2 [("One",1,0),("Two",2,0),("Three",3,0)]
[1,2,3]
(0.06 secs, 4332272 bytes)
>>> map sel3 [("One",1,0),("Two",2,0),("Three",3,0)]
[0,0,0]
(0.01 secs, 2140016 bytes)
>>> map sel4 [("One",1,0),("Two",2,0),("Three",3,0)]

<interactive>:6:5:
.... error

вы также можете использовать объектив пакет:

> import Control.Lens
> Prelude Control.Lens> view _1 (1,2)  -- Or (1,2) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3) -- Or (1,2,3) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3,4) -- Or (1,2,3,4) ^. _1
1
> Prelude Control.Lens> view _1 (1,2,3,4,5) -- Or (1,2,3,4,5) ^. _1
1

это работает не только для первого элемента

> import Control.Lens
> Prelude Control.Lens> view _2 (1,2)  -- Or (1,2) ^. _2
2
> Prelude Control.Lens> view _3 (1,2,3) -- Or (1,2,3) ^. _3
3
> Prelude Control.Lens> view _4 (1,2,3,4) -- Or (1,2,3,4) ^. _4
4
> Prelude Control.Lens> view _5 (1,2,3,4,5) -- Or (1,2,3,4,5) ^. _5
5

Я также написал ответ на аналогичный вопрос, который охватывает больше, чем просто кортежи: https://stackoverflow.com/a/23860744/128583


вы могли бы сделать это:

Prelude> let [(a,_,_)]=[("string",1,1)]
Prelude> a
"string"

Я бы просто определить функцию

fst3 :: (a,b,c) -> a
fst3 (x,_,_) = x

это легко понять и не имеет странного типа (Тип sel1 is Sel1 a b => a -> b что может сбить с толку)

или вы можете извлечь значение, которое вас интересует, с помощью patternmatching, как в [x | (x,_,_) <- myThreeTupleList.

наконец, лучшим решением является использование более структурированного типа данных! Конечно, строка и два Инта несут больше смысла, и это хорошая идея, чтобы как-то кодировать это...