Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8697455
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T01:31:47+00:00 2026-06-13T01:31:47+00:00

I want to write a Haskell program that queries information about a darcs repository.

  • 0

I want to write a Haskell program that queries information about a darcs repository. Instead of invoking the darcs executable and parse the results, I would rather use the darcs library directly. It is said to be “very much work in progress” and to “lack a stable API”, but seems usable.

I think I could answer my questions by studying the darcsden source code, for example, starting with this module, but I think it may be helpful not only to me if someone knowledgeable would provide a commented introduction to supplement such a study.

So, here is a concrete example.

How can I compute for a given file the most recent patch that affected it along with the date, author, and name of the patch? It would be extra useful if you explain the key library functions used in your solution.


Edit:

Here are some remarks that might not be obvious to someone unfamiliar with the source code of darcs. I learned them from Jason Dagit’s master thesis and hope they are helpful to understand the answer given by Ganesh.

In Darcs, patches have a pre- and a post-context representing the state of the repository before and after applying the patch. In source code, these contexts are modeled using phantom types on the type of patches. These phantom types are called witnesses and seal2 is used to get rid of them.

In lists of patches, only the very first pre-context and the very last post-context are represented in the type. All other contexts are hidden using existential types. Darcs defines forward lists (called FL) and reverse lists (called RL). Reverse lists store patches in reverse (chronological) order (modulo patch reordering done by darcs). Reverse lists can be used to access the most recent patch in the head position. All functions with RL in their name create or operate on such reverse lists.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T01:31:48+00:00Added an answer on June 13, 2026 at 1:31 am
    -- This works with darcs 2.9.5 (a tag in the development repo
    -- at http://darcs.net/screened).
    --
    -- It should work with darcs 2.8.2 with the following changes:
    --  - some minor namespace changes
    --  - change withRepositoryDirectory to pass [] instead of YesUseCache
    --  - comment out the line below that uses the "patch index"
    
    import Control.Applicative ( (<$>) )
    
    import Darcs.Patch.Info ( PatchInfo )
    import Darcs.Patch.Inspect ( listTouchedFiles )
    import Darcs.Patch.PatchInfoAnd ( info )
    import Darcs.Patch.Set ( newset2RL )
    import Darcs.Patch.Witnesses.Ordered ( mapRL )
    import Darcs.Patch.Witnesses.Sealed ( seal2, unseal2 )
    
    import Darcs.Repository
        ( withRepositoryDirectory, RepoJob(..), readRepo )
    import Darcs.Repository.FileMod ( filterPatches )
    import Darcs.Repository.Flags ( UseCache(..) )
    
    import Data.Maybe ( listToMaybe )
    
    getChange
        :: FilePath                -- ^repository directory
        -> FilePath                -- ^file path
        -> IO (Maybe PatchInfo)    -- ^patch metadata
    getChange repoDir fileName =
    
        -- Select the repository from repositoryDirectory.
        --
        -- The function parameter to 'RepoJob' needs to be polymorphic
        -- in the underlying patch type (darcs-1 or darcs-2).
    
        withRepositoryDirectory YesUseCache repoDir $ RepoJob $ \repo -> do
    
        -- 'readRepo' gives us a PatchSet, a lazy witnessed list of all
        -- the patches structured by "clean tags".
        --
        -- We use 'newset2RL' to get rid of the tag structure as we don't
        -- need it, and 'mapRL seal2' to get rid of the witnesses which we
        -- also don't need. The result is of type '[Sealed2 p]', where 'p'
        -- is the underlying patch type of the repository we are reading
        -- (either darcs-1 or darcs-2)
    
        patches <- mapRL seal2 . newset2RL <$> readRepo repo
    
    
        -- Use the recently introduced "patch index" to filter the list of
        -- patches from the repo down to ones that just touch 'fileName'.
        --
        -- This step is optional: we can remove it and the result will be
        -- the same, but substantially slower on large repositories where
        -- the patch we want is far back in the repo.
    
        patches <- filterPatches repo [fileName] patches
    
        -- Use 'filter' and 'listToMaybe' to get the first patch that touches
        -- 'fileName'.
        --
        -- The filter is superfluous in this simple case if the patch
        -- index was used, but doesn't cost much if so.
        --
        -- Note that this doesn't track renames, so isn't suitable for
        -- finding anything but the last patch that touched 'fileName'.
        --
        -- 'unseal2' is used to lift a function that works on witnessed
        -- patches to one that works on "sealed" patches.
    
        let wanted = unseal2 (\patch -> fileName `elem` listTouchedFiles patch)
        let thepatch = listToMaybe . filter wanted $ patches
    
        -- Finally, return the metadata of the patch.
        --
        -- Things get a little bit more complex if we want to deal
        -- with the contents of the patch, because the specific
        -- patch type isn't known statically - it might be
        -- darcs-1 or darcs-2.
        --
        -- The best approach is to write a polymorphic function that
        -- can accept any instance of 'RepoPatch'.
    
        return (fmap (unseal2 info) thepatch)
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I want to write a program in Prolog that confirms if a b-tree of
I am teaching myself Haskell. I want to write a function that recursively finds
I'm trying to learn Haskell and want to write a small program which prints
I am writing a Haskell program where I want to write to an already
I want to write a program that uses the GPL-licensed pandoc for Markdown processing.
I'm new to Haskell and Snap and I want to write a simple bug-tracking
I want to write <a href=product.php?id=5> as product/5.I am not talking about user to
I want to write a program to contact a PHP script online, and show
I've got a Haskell program that needs to execute a separate (third party) binary;
I'm so proud of myself! ^_^ I can finally write Haskell functions that work!

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.