-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #128 from input-output-hk/newhoggy/improved-featur…
…e-ergonomics Improved feature ergonomics
- Loading branch information
Showing
9 changed files
with
225 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,46 @@ | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE KindSignatures #-} | ||
{-# LANGUAGE LambdaCase #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
{-# LANGUAGE StandaloneDeriving #-} | ||
|
||
{-# OPTIONS_GHC -Wno-deprecations #-} | ||
|
||
module Cardano.Api.Feature | ||
( FeatureValue (..) | ||
, FeatureInEra(..) | ||
, featureInShelleyBasedEra | ||
, valueOrDefault | ||
, asFeatureValue | ||
, asFeatureValueInShelleyBasedEra | ||
, isFeatureValue | ||
( Featured (..) | ||
, asFeaturedInEra | ||
, asFeaturedInShelleyBasedEra | ||
) where | ||
|
||
import Cardano.Api.Eras | ||
|
||
import Data.Kind | ||
|
||
-- | A class for features that are supported in some eras but not others. | ||
class FeatureInEra (feature :: Type -> Type) where | ||
-- | Determine the value to use for a feature in a given 'CardanoEra'. | ||
-- Note that the negative case is the first argument, and the positive case is the second as per | ||
-- the 'either' function convention. | ||
featureInEra :: () | ||
=> a -- ^ Value to use if the feature is not supported in the era | ||
-> (feature era -> a) -- ^ Function to get thealue to use if the feature is supported in the era | ||
-> CardanoEra era -- ^ Era to check | ||
-> a -- ^ The value to use | ||
|
||
instance FeatureInEra ShelleyBasedEra where | ||
featureInEra no yes = \case | ||
ByronEra -> no | ||
ShelleyEra -> yes ShelleyBasedEraShelley | ||
AllegraEra -> yes ShelleyBasedEraAllegra | ||
MaryEra -> yes ShelleyBasedEraMary | ||
AlonzoEra -> yes ShelleyBasedEraAlonzo | ||
BabbageEra -> yes ShelleyBasedEraBabbage | ||
ConwayEra -> yes ShelleyBasedEraConway | ||
|
||
-- | Determine the value to use for a feature in a given 'ShelleyBasedEra'. | ||
featureInShelleyBasedEra :: () | ||
=> FeatureInEra feature | ||
=> a | ||
-> (feature era -> a) | ||
-> ShelleyBasedEra era | ||
-> a | ||
featureInShelleyBasedEra no yes = featureInEra no yes . shelleyBasedToCardanoEra | ||
|
||
-- | A value of type @'FeatureValue' feature era a@ is either: | ||
data FeatureValue feature era a where | ||
-- | A value is available for this feature in this era | ||
FeatureValue | ||
-- | A value only if the feature is supported in this era | ||
data Featured feature era a where | ||
Featured | ||
:: feature era | ||
-- ^ The witness that the feature is supported in this era | ||
-> a | ||
-- ^ The value to use | ||
-> FeatureValue feature era a | ||
|
||
-- | No value is available for this feature in this era | ||
NoFeatureValue | ||
:: FeatureValue feature era a | ||
|
||
deriving instance (Eq a, Eq (feature era)) => Eq (FeatureValue feature era a) | ||
deriving instance (Show a, Show (feature era)) => Show (FeatureValue feature era a) | ||
-> Featured feature era a | ||
|
||
-- | Determine if a value is defined. | ||
-- | ||
-- If the value is not defined, it could be because the feature is not supported or | ||
-- because the feature is supported but the value is not available. | ||
isFeatureValue :: FeatureValue feature era a -> Bool | ||
isFeatureValue = \case | ||
NoFeatureValue -> False | ||
FeatureValue _ _ -> True | ||
deriving instance (Eq a, Eq (feature era)) => Eq (Featured feature era a) | ||
deriving instance (Show a, Show (feature era)) => Show (Featured feature era a) | ||
|
||
-- | Get the value if it is defined, otherwise return the default value. | ||
valueOrDefault :: a -> FeatureValue feature era a -> a | ||
valueOrDefault defaultValue = \case | ||
NoFeatureValue -> defaultValue | ||
FeatureValue _ a -> a | ||
instance Functor (Featured feature era) where | ||
fmap f (Featured feature a) = Featured feature (f a) | ||
|
||
-- | Attempt to construct a 'FeatureValue' from a value and era. | ||
-- If the feature is not supported in the era, then 'NoFeatureValue' is returned. | ||
asFeatureValue :: () | ||
asFeaturedInEra :: () | ||
=> FeatureInEra feature | ||
=> a | ||
-> CardanoEra era | ||
-> FeatureValue feature era a | ||
asFeatureValue value = featureInEra NoFeatureValue (`FeatureValue` value) | ||
-> Maybe (Featured feature era a) | ||
asFeaturedInEra value = featureInEra Nothing (Just . flip Featured value) | ||
|
||
-- | Attempt to construct a 'FeatureValue' from a value and a shelley-based-era. | ||
asFeatureValueInShelleyBasedEra :: () | ||
asFeaturedInShelleyBasedEra :: () | ||
=> FeatureInEra feature | ||
=> a | ||
-> ShelleyBasedEra era | ||
-> FeatureValue feature era a | ||
asFeatureValueInShelleyBasedEra value = asFeatureValue value . shelleyBasedToCardanoEra | ||
-> Maybe (Featured feature era a) | ||
asFeaturedInShelleyBasedEra value = asFeaturedInEra value . shelleyBasedToCardanoEra |
56 changes: 56 additions & 0 deletions
56
cardano-api/internal/Cardano/Api/Feature/ConwayEraOnwards.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{-# LANGUAGE ConstraintKinds #-} | ||
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE LambdaCase #-} | ||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE StandaloneDeriving #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
{-# LANGUAGE TypeOperators #-} | ||
|
||
module Cardano.Api.Feature.ConwayEraOnwards | ||
( ConwayEraOnwards(..) | ||
, conwayEraOnwardsConstraints | ||
, conwayEraOnwardsToCardanoEra | ||
, conwayEraOnwardsToShelleyBasedEra | ||
) where | ||
|
||
import Cardano.Api.Eras | ||
|
||
import Cardano.Crypto.Hash.Class (HashAlgorithm) | ||
import qualified Cardano.Ledger.Api as L | ||
|
||
data ConwayEraOnwards era where | ||
ConwayEraOnwardsConway :: ConwayEraOnwards ConwayEra | ||
|
||
deriving instance Show (ConwayEraOnwards era) | ||
deriving instance Eq (ConwayEraOnwards era) | ||
|
||
instance FeatureInEra ConwayEraOnwards where | ||
featureInEra no yes = \case | ||
ByronEra -> no | ||
ShelleyEra -> no | ||
AllegraEra -> no | ||
MaryEra -> no | ||
AlonzoEra -> no | ||
BabbageEra -> no | ||
ConwayEra -> yes ConwayEraOnwardsConway | ||
|
||
type ConwayEraOnwardsConstraints era = | ||
( L.EraCrypto (ShelleyLedgerEra era) ~ L.StandardCrypto | ||
, HashAlgorithm (L.HASH (L.EraCrypto (ShelleyLedgerEra era))) | ||
, L.ConwayEraTxBody (ShelleyLedgerEra era) | ||
) | ||
|
||
conwayEraOnwardsConstraints | ||
:: ConwayEraOnwards era | ||
-> (ConwayEraOnwardsConstraints era => a) | ||
-> a | ||
conwayEraOnwardsConstraints = \case | ||
ConwayEraOnwardsConway -> id | ||
|
||
conwayEraOnwardsToCardanoEra :: ConwayEraOnwards era -> CardanoEra era | ||
conwayEraOnwardsToCardanoEra = shelleyBasedToCardanoEra . conwayEraOnwardsToShelleyBasedEra | ||
|
||
conwayEraOnwardsToShelleyBasedEra :: ConwayEraOnwards era -> ShelleyBasedEra era | ||
conwayEraOnwardsToShelleyBasedEra = \case | ||
ConwayEraOnwardsConway -> ShelleyBasedEraConway |
Oops, something went wrong.