user2214957
user2214957

Reputation:

Haskell Performing fst on a 3 part tuple

I have the following Haskell tuple:

       [("string",1,1)]

I need to extract the first element of this, obviously using 'fst' wont work here as there are 3 components.

What is the best method to use? sel ?

Upvotes: 13

Views: 9625

Answers (5)

zurgl
zurgl

Reputation: 1930

sel can be used in the following manner:

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

It works like any other function with map

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

The main advantage is that it works for a bigger tuple

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

as well as the standard tuple

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

hence there is no need of handling them separately.


Some more examples:

>>> 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

Upvotes: 9

Davorak
Davorak

Reputation: 7444

You can also use the lens package:

> 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

This works for more than just the first element

> 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

I also wrote an answer to a similar question that covers more than just tuples: https://stackoverflow.com/a/23860744/128583

Upvotes: 5

yatima2975
yatima2975

Reputation: 6610

I would just define a function

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

That's easy to understand and doesn't have a weird type (the type of sel1 is Sel1 a b => a -> b which may be confusing)

Or you could extract the value which you're interested in via patternmatching as in [x | (x,_,_) <- myThreeTupleList.

Finally, the best solution is to use a more structured data type! Surely, the string and the two ints carry more meaning and it's a good idea to encode that somehow...

Upvotes: 4

su-
su-

Reputation: 3166

You could do this:

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

Upvotes: 3

Martinsos
Martinsos

Reputation: 1693

You could just type your own function (we will use pattern matching) for this:

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

and you use it like:

fst3 ("string", 1, 1)

Upvotes: 18

Related Questions