Reverse a list in haskell

后端 未结 5 794
野的像风
野的像风 2020-12-14 19:06

I am trying to reverse a list.

Following is my code:

reverseList :: [Int] -> [Int]
reverseList [] = []
reverseList (x:xs) =  x:reverseList xs
         


        
5条回答
  •  佛祖请我去吃肉
    2020-12-14 19:49

    Basically the naive algorithm which uses appending

    revList [] = []
    revList (x:xs) = revList xs ++ [x]
    

    is inefficient since appending is an O(n) operation where n is the length of the first (left) parameter of the ++ operator. So the revList function above turns out to be O(n(n-1)/2) ~ O(n^2).

    So for such append heavy tasks there are the Difference List data type.

    A difference list is just a list expressed as a function. What i mean is, a list like [1,2,3] when expressed in DList type would be \xs -> [1,2,3] ++ xs or in short ([1,2,3] ++)

    type DList a = [a] -> [a]
    
    toDList :: [a] -> DList a
    toDList xs  = (xs ++ )
    
    fromDList :: DList a -> [a]
    fromDList f = f []
    

    This is sort of cool because since DLists are functions we can append them by composition (.) operator and get a new DList. In other words toDList (xs ++ ys) == (toDList xs) . (toDList ys).

    So how is this useful? By using nested function compositions we can reverse our list in a similar fashion to revList function but it will cost us much less. Only O(n) since every function composition is O(1).

    revList' :: [a] -> DList a
    revList' []     = toDList []
    revList' (x:xs) = revList' xs . toDList [x]
    

    Now that we have the reversed [a] in DList a type all we need to apply fromDList

    fastReverse :: [a] -> [a]
    fastReverse = fromDList . revList'
    

    The Difference List data type is not as simple as i have shown above. It can have Monoid, Functor and MonadT instances. For more on this useful data type check Data.DList

提交回复
热议问题