Reputation: 121
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
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:
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
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