Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Position based tuple pattern match in Haskell

Is it possible to pattern match tuples in Haskell, but without knowing the dimension of tuple? I want to create a function which mach against any tuple, which first element is A, like:

data A = A Int
test args@(A a,..) = a

I know there is Data.Tuple.Select module and I can use it like this:

test args = case sel1 args of
    A a -> a
    ...

But is this the only way of doing this or has Haskell got some default mechanisms to match against any dimension tuple?

like image 443
Wojciech Danilo Avatar asked Dec 11 '22 12:12

Wojciech Danilo


2 Answers

You could use the ViewPatterns extension to pattern match the result of a function applied to an argument:

{-# LANGUAGE ViewPatterns #-}

data A = A Int
test (fst -> A a) = a

You could use lenses to project out arbitrary fields:

{-# LANGUAGE ViewPatterns #-}

import Control.Lens
import Control.Arrow ((&&&))

data A = A Int
test (fields _1 _3 -> (A x, A y)) = x + y

fields f1 f2 = (^.f1) &&& (^.f2)

-- > test (A 1, A 2, A 3)
-- > 4
like image 188
William Casarin Avatar answered Jan 04 '23 11:01

William Casarin


If you don't want to use type classes, you could also use nested tuples. So instead of having a tuple of type (A, B, C, D) you have a tuple of (A, (B, (C, D))).

You could then easily match against the first element of a however deeply nested tuple, like this:

test :: (A, b) -> Int
test (A a, _) = a
like image 27
bzn Avatar answered Jan 04 '23 09:01

bzn