rock: A build system for incremental, parallel, and demand-driven computations

[ bsd3, development, library ] [ Propose Tags ]

Flags

Manual Flags

NameDescriptionDefault
examples

"Build examples"

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

Versions [RSS] 0.1.0.0, 0.1.0.1, 0.2.0.0, 0.3.0.0, 0.3.1.0, 0.3.1.1, 0.3.1.2
Change log CHANGELOG.md
Dependencies base (>=4.7 && <5), constraints-extras (>=0.4.0 && <0.5), dependent-hashmap (>=0.1.0 && <0.2), dependent-sum (>=0.7.2 && <0.8), dependent-sum-template, deriving-compat (>=0.6.5 && <0.7), hashable (>=1.4.3 && <1.5), lifted-base (>=0.2.3 && <0.3), monad-control (>=1.0.3 && <1.1), mtl (>=2.3.1 && <2.4), rock, transformers (>=0.6.1 && <0.7), transformers-base (>=0.4.6 && <0.5), unordered-containers (>=0.2.19 && <0.3) [details]
License BSD-3-Clause
Copyright 2018-2023 Olle Fredriksson
Author Olle Fredriksson
Maintainer fredriksson.olle@gmail.com
Category Development
Home page https://github.com/ollef/rock#readme
Source repo head: git clone https://github.com/ollef/rock
Uploaded by placidex at 2023-10-13T17:06:46Z
Distributions
Executables rock-spreadsheet
Downloads 1636 total (22 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for rock-0.3.1.2

[back to package description]

rock

Build Status CI Status Hackage

A build system inspired by Build systems à la carte.

Used in Sixten, Sixty and Eclair to achieve incremental and query driven compiler architectures.

Example

{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language StandaloneDeriving #-}
{-# language TemplateHaskell #-}

import Control.Monad.IO.Class
import Data.GADT.Compare.TH (deriveGEq)
import Data.Hashable
import Data.Some
import Data.IORef
import qualified Rock

data Query a where
  A :: Query Integer
  B :: Query Integer
  C :: Query Integer
  D :: Query Integer

deriving instance Show (Query a)
deriveGEq ''Query

instance Hashable (Query a) where
  hashWithSalt salt query =
    case query of
      A -> hashWithSalt salt (0 :: Int)
      B -> hashWithSalt salt (1 :: Int)
      C -> hashWithSalt salt (2 :: Int)
      D -> hashWithSalt salt (3 :: Int)

instance Hashable (Some Query) where
  hashWithSalt salt (Some query) = hashWithSalt salt query

rules :: Rock.Rules Query
rules key = do
  liftIO $ putStrLn $ "Fetching " <> show key
  case key of
    A -> pure 10
    B -> do
      a <- Rock.fetch A
      pure $ a + 20
    C -> do
      a <- Rock.fetch A
      pure $ a + 30
    D ->
      (+) <$> Rock.fetch B <*> Rock.fetch C

main :: IO ()
main = do
  do
    liftIO $ putStrLn "Running"
    result <- Rock.runTask rules (Rock.fetch D)
    print result
  do
    liftIO $ putStrLn "Running with memoisation"
    memoVar <- newIORef mempty
    result <- Rock.runTask (Rock.memoise memoVar rules) (Rock.fetch D)
    liftIO $ print result

Prints

Running
Fetching D
Fetching B
Fetching A
Fetching C
Fetching A
70
Running with memoisation
Fetching D
Fetching B
Fetching A
Fetching C
70

Note: Besides pure computations as shown above, the Task data type implements MonadIO, so you can lift IO actions into the Task monad by using liftIO!

Query parameters

If you need to parametrize your queries (e.g. typechecking one specific file), you can do this by adding additional arguments to your Query datatype:

data Query a where
  Parse :: FilePath -> Query AST
  Typecheck :: FilePath -> Query (Either TypeError TypedAST)

rules :: Rock.Rules Query
rules key = case key of
  Parse file -> do
    _ -- parse the file..
  Typecheck file -> do
    ast <- Rock.fetch (Parse file)
    _ -- typecheck file..

Contributions

... are very welcome, especially in the areas of documentation and examples.