cabal-install-solver-3.12.1.0: The command-line interface for Cabal and Hackage.

Safe Haskell | None
Language | Haskell2010

Distribution.Solver.Modular.Preference

Description

Reordering or pruning the tree in order to prefer or make certain choices.

Synopsis

- avoidReinstalls :: (PN -> Bool) -> EndoTreeTrav d c
- deferSetupExeChoices :: EndoTreeTrav d c
- deferWeakFlagChoices :: EndoTreeTrav d c
- enforceManualFlags :: Map PN [LabeledPackageConstraint] -> EndoTreeTrav d c
- enforcePackageConstraints :: Map PN [LabeledPackageConstraint] -> EndoTreeTrav d c
- enforceSingleInstanceRestriction :: Tree d c -> Tree d c
- firstGoal :: EndoTreeTrav d c
- preferBaseGoalChoice :: EndoTreeTrav d c
- preferLinked :: EndoTreeTrav d c
- preferPackagePreferences :: (PN -> PackagePreferences) -> EndoTreeTrav d c
- preferReallyEasyGoalChoices :: EndoTreeTrav d c
- onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason
- sortGoals :: (Variable QPN -> Variable QPN -> Ordering) -> EndoTreeTrav d c
- pruneAfterFirstSuccess :: EndoTreeTrav d c

# Documentation

avoidReinstalls :: (PN -> Bool) -> EndoTreeTrav d c #

Avoid reinstalls.

This is a tricky strategy. If a package version is installed already and the same version is available from a repo, the repo version will never be chosen. This would result in a reinstall (either destructively, or potentially, shadowing). The old instance won't be visible or even present anymore, but other packages might have depended on it.

TODO: It would be better to actually check the reverse dependencies of installed packages. If they're not depended on, then reinstalling should be fine. Even if they are, perhaps this should just result in trying to reinstall those other packages as well. However, doing this all neatly in one pass would require to change the builder, or at least to change the goal set after building.

deferSetupExeChoices :: EndoTreeTrav d c #

Deal with setup and build-tool-depends dependencies after regular dependencies, so we will link setup/exe dependencies against package dependencies when possible

deferWeakFlagChoices :: EndoTreeTrav d c #

Transformation that tries to avoid making weak flag choices early. Weak flags are trivial flags (not influencing dependencies) or such flags that are explicitly declared to be weak in the index.

enforceManualFlags :: Map PN [LabeledPackageConstraint] -> EndoTreeTrav d c #

Transformation that tries to enforce the rule that manual flags can only be set by the user.

If there are no constraints on a manual flag, this function prunes all but the default value. If there are constraints, then the flag is allowed to have the values specified by the constraints. Note that the type used for flag values doesn't need to be Bool.

This function makes an exception for the case where there are multiple goals for a single package (with different qualifiers), and flag constraints for manual flag x only apply to some of those goals. In that case, we allow the unconstrained goals to use the default value for x OR any of the values in the constraints on x (even though the constraints don't apply), in order to allow the unconstrained goals to be linked to the constrained goals. See https://github.com/haskell/cabal/issues/4299. Removing the single instance restriction (SIR) would also fix #4299, so we may want to remove this exception and only let the user toggle manual flags if we remove the SIR.

This function does not enforce any of the constraints, since that is done by `enforcePackageConstraints`.

enforcePackageConstraints :: Map PN [LabeledPackageConstraint] -> EndoTreeTrav d c #

Traversal that tries to establish various kinds of user constraints. Works by selectively disabling choices that have been ruled out by global user constraints.

enforceSingleInstanceRestriction :: Tree d c -> Tree d c #

Enforce ghc's single instance restriction

From the solver's perspective, this means that for any package instance (that is, package name + package version) there can be at most one qualified goal resolving to that instance (there may be other goals _linking_ to that instance however).

firstGoal :: EndoTreeTrav d c #

Always choose the first goal in the list next, abandoning all other choices.

This is unnecessary for the default search strategy, because it descends only into the first goal choice anyway, but may still make sense to just reduce the tree size a bit.

preferBaseGoalChoice :: EndoTreeTrav d c #

Transformation that tries to make a decision on base as early as possible by pruning all other goals when base is available. In nearly all cases, there's a single choice for the base package. Also, fixing base early should lead to better error messages.

preferLinked :: EndoTreeTrav d c #

Prefer to link packages whenever possible.

preferPackagePreferences :: (PN -> PackagePreferences) -> EndoTreeTrav d c #

preferReallyEasyGoalChoices :: EndoTreeTrav d c #

Transformation that prefers goals with lower branching degrees.

When a goal choice node has at least one goal with zero or one children, this function prunes all other goals. This transformation can help the solver find a solution in fewer steps by allowing it to backtrack sooner when it is exploring a subtree with no solutions. However, each step is more expensive.

onlyConstrained :: (PN -> Bool) -> EndoTreeTrav d QGoalReason #

Require all packages to be mentioned in a constraint or as a goal.

sortGoals :: (Variable QPN -> Variable QPN -> Ordering) -> EndoTreeTrav d c #

Sort all goals using the provided function.

pruneAfterFirstSuccess :: EndoTreeTrav d c #

Reduce the branching degree of the search tree by removing all choices after the first successful choice at each level. The returned tree is the minimal subtree containing the path to the first backjump.