Se podría utilizar algo como
data MyList a = MyNil
| MyCons a a (MyList a)
Esto asegura que su lista se alarga dos elementos a la vez. Esto es equivalente al comentario de Alexandre, pero vale la pena analizarlo con cierto detalle.
Junto con algunos de/a la conversión funciones como
fromMyList :: MyList a -> [a]
fromMyList MyNil = []
fromMyList (MyCons x y rest) = x : y : fromMyList rest
toMyList :: [a] -> Maybe (MyList a)
toMyList [] = Just MyNil
toMyList [_] = Nothing
toMyList (x:y:rest) = fmap (MyCons x y) (toMyList rest)
toMyListError :: [a] -> MyList a
toMyListError [] = MyNil
toMyListError [_] = error "Length of list has to be even"
toMyListError (x:y:rest) = MyCons x y (toMyListError rest)
-- these two may be a bit more difficult to use...
fromMyListTuple :: MyList a -> [(a,a)]
fromMyListTuple MyNil = []
fromMyListTuple (MyCons x y rest) = (x,y) : fromMyListTuple rest
toMyListTuple :: [(a,a)] -> MyList a
toMyListTuple = foldr (\(x,y) -> MyCons x y) MyNil
se hace posible reutilizar las funciones de lista existentes con un poco de pensamiento:
myAppend :: MyList a -> MyList a -> MyList a
myAppend xs ys = toMyListError (fromMyList xs ++ fromMyList ys)
Pero todo depende de lo que realmente quiere para hacer con estas listas!
Puede indicar muchas propiedades de la cantidad de elementos en el contenedor de esta manera, vea el trabajo de Chris Okasaki, por ejemplo. Otras condiciones podrían ser posibles también, pero en la mayoría de los casos estarás mejor con el enfoque de Darío.
Pero, por último, tenga en cuenta que si su tipo es ser completamente polimórfico, ¡no puede usar mucha más información sobre las listas contenidas que el número de elementos en ella de todos modos!
'data MyList = List (a, a)'? –
Alexandre, no es que permite Lista ([], []), Lista ([1], []), Lista ([1,2,3], [1,2]) que no son pares, a pesar de tener 2 elementos validos? – Alex
Alexandre significaba listas de tuplas: [(a, a)]. De esta forma, tendrá un número par de a's, como [(1,2), (5,2), (2,10)]. – sdcvvc