Reputation: 165
I'm working on an university assignment and the the task involves building a list in the form of nested pairs. For the pairs there exists a datastructure like:
data Data = Pair { first :: Data, second :: Data } | ...
I tried to write an append function that takes a pair and the new value which is appended to the given pair:
append :: Pair -> Data -> Pair
append p new = append' p p new
where
append' :: Pair -> Pair -> Data -> Pair
append' p cur@(Pair Nil _) new = p where { cur = cur { first=new } }
append' p cur@(Pair _ Nil) new = p where { cur = cur { second=(Pair new Nil) } }
append' p cur@(Pair _ (Pair _ _)) new = append' p (second cur) new
The idea was to always keep a reference to the given pair that is returned at the end (p) and at the same time move (cur) recursively through the nested Pair structure until the end is encountered (second is Nil) at which then the new element is added in form of another pair.
I assume this doesn't work because it requires pass by reference which is not the case in side-effect-less Haskell.
I'd be very grateful if anybody could point me in the right direction on how to solve this problem.
Upvotes: 0
Views: 152
Reputation: 476574
Haskell conceptually has not really references. Sure Haskell uses a lot of references (to reduce for instance the memory load), and there are modules like Data.IORef
where we can use references by using IO
. But such functions do not really have conceptual references.
Furthermore you use something like p where {cur = cur {first = new } }
, which seems like you look for an assignment. Haskell has no assignments, it only has declarations.
In case you want to append, you thus need to construct a new Pair
. We can for instance use:
append :: Pair -> Data -> Pair
append (Pair Nil r) dat = Pair dat r
append (Pair l Nil) dat = Pair l dat
append (Pair l r) dat = Pair l (append r dat)
So for the first two lines, we construct a new pair where we replace the Nil
by data
. In the latter case (both are non-Nil
), we construct a new pair, where we make a recursive append
call to calculate the new right part.
Upvotes: 4