Sibi
Sibi

Reputation: 48644

Pipes equivalent code for simple functions

Let's say, I have the following types:

type LinkID = Int

data Link = Link {
  lid :: LinkID,
  llength :: Int
  }

data Snap = Snap {
  slid :: LinkID,
  slength :: Int
  }

Now, I want to write a pipes based function which does this:

getSnaps :: LinkID -> [Link] -> [Snap] -> [(LinkID, [Snap])]
getSnaps l lks snp = map (\x -> (lid x, filter (\y -> lid x == slid y) snp)) a
  where a = filter (\x -> lid x > l) lks

Assumming that I already have Producers of Link and Snap, how can I implement the above getSnaps function in the Pipes world from these two Producers:

psnap :: Producer Snap IO ()
psnap = undefined

plink :: Producer Link IO ()
plink = undefined

The actual types of psnap and plink are more involved (created out by using attoparsec-pipes), but I would like to know how to implement the functionality of getSnaps from psnap and plink. Is there a proper way to solve this type of problem ?

Upvotes: 3

Views: 146

Answers (1)

Gabriella Gonzalez
Gabriella Gonzalez

Reputation: 35089

The solution I came up with is pretty similar to your code. I just replaced map with Pipes.Prelude.map and one of the filters with Pipes.Prelude.filter:

import Pipes
import qualified Pipes.Prelude as Pipes

type LinkID = Int

data Link = Link
    { lid :: LinkID
    , llength :: Int
    }

data Snap = Snap
    { slid :: LinkID
    , slength :: Int
    }

getSnaps
    :: Monad m
    => LinkID
    -> Producer  Link            m ()
    -> Producer  Snap            m ()
    -> Producer (LinkID, [Snap]) m ()
getSnaps l lks snp = do
    snp' <- lift (Pipes.toListM snp)  -- Cache `snp` into the list `snp'`
    lks >-> Pipes.filter (\x -> lid x > l)
        >-> Pipes.map (\x -> (lid x, filter (\y -> lid x == slid y) snp'))

Note that there is one non-trivial part, which is that the above solution strictly loads the snp Producer's contents into the list snp'. The reason for this is that we have to use the contents of the list repeatedly, so we need to cache the entire list in memory for repeated usage.

Upvotes: 2

Related Questions