Lucia Guzheim
Lucia Guzheim

Reputation: 121

How to count the length of a tuple in Haskell?

I tried searching in web and stackexchange, but surprisingly no one asked how to calculate length of a tuple in Haskell in the form below.

So suppose you have tuple like (1,2,3,4) or (1,3,5,6,7) in Haskell and wish to write the length function that calculates length of a tuple. How can I do this? For list I know how I will be able to do so using recursion without explicitly invoking built-in functions. But tuple is different, and I can't use "head"-"tail" distinction.

Will the method involve creating a new data type?

Upvotes: 2

Views: 2302

Answers (2)

leftaroundabout
leftaroundabout

Reputation: 120751

The reason you don't find anything on this is that it doesn't make a lot of sense to count the length of a tuple:

  • It is pre-determined a compile time (i.e. you might just as well hard-code it)
  • There's not really much you could do with that information: unlike with e.g. a list, it's not possible to index specific entries in a generic tuple.

That said, it is possible to achieve your goal, however this shouldn't be a normal function but a type-level function, aka type family. Using singleton type nats:

{-# LANGUAGE TypeFamilies, DataKinds #-}
import Data.Singletons
import Data.Singletons.TypeLits

type family TupLength a :: Nat where
  TupLength () = 0
  TupLength (a,b) = 2
  TupLength (a,b,c) = 3
  TupLength (a,b,c,d) = 4
  -- ...
  TupLength x = 1

Then

> mapM_ print [ natVal (sing :: SNat (TupLength ()))
              , natVal (sing :: SNat (TupLength (Int,String,Double)))
              , natVal (sing :: SNat (TupLength Bool)) ]
0
3
1

Upvotes: 7

Roman Cheplyaka
Roman Cheplyaka

Reputation: 38758

One possible answer (using just the base library) is

import Data.Data
import Data.Functor.Const

length :: Data a => a -> Int
length =
  getConst .
  gfoldl (\(Const c) _ -> Const (c+1)) (const 0)

I gave a whole talk on this subject at London Haskell recently. The slides are here, but the video has not been published yet.

Upvotes: 5

Related Questions