I just found out that the !!
operator is for lists only:
(!!) :: [a] -> Int -> a
So I searched for alternatives at hoogle:
I am very surprised not to have found one!
So I ask:
- What is the way to access a ziplist by index without converting it back to list?
- What hoogle search would have found it
Of course, answering 1 goes a long way towards answering 2, because I'd have the type signature
CodePudding user response:
ZipList
is a newtype
, so there is no conversion. It just is that same list.
newtype ZipList a = ZipList { getZipList :: [a] }
As the Report states in section 4.2.3 Datatype Renamings,
A declaration of the form newtype cx => T u1 … uk = N t introduces a new type whose representation is the same as an existing type.
(emphasis mine). When the code runs, the ZipList
tag isn't there at all. Thus,
getZipList
is a zero cost no-op.
As an illustration, treating a ZipList Int
value as a [Int]
value is perfectly fine. Observe:
GHCi> coerce (ZipList [1,2,3] :: ZipList Int) :: [Int]
[1,2,3]
it :: [Int]
Thus the data constructor ZipList
is just a compile-time tag with which we declare our intentions as to which applicative implementation is to be used. Specifically, the zipping one, not the nested loops one (of the regular []
).
As to the !!
itself, it should be avoided. Repeated calls to it with growing index values will cause quadratic behavior. Any number of higher-order functions can be used instead, or a direct recursion can be coded if needed, processing a list's elements one by one without re-tracing the list from the start anew for each element.