Skip to content

Instantly share code, notes, and snippets.

@Nolrai
Created September 26, 2019 08:59
Show Gist options
  • Save Nolrai/1fce081ec785b240cf4a32d4a7cd4059 to your computer and use it in GitHub Desktop.
Save Nolrai/1fce081ec785b240cf4a32d4a7cd4059 to your computer and use it in GitHub Desktop.
-- Why is it reading 'Piece v' as 'Piece v0' Is v somehow not in scope?
135:6: error:
• Couldn't match type ‘Piece v0’ with ‘Piece v’
Expected type: (Name TypeExpr -> m (Name TypeExpr))
-> Either [Piece v] (Name TypeExpr)
Actual type: (Name TypeExpr -> m (Name TypeExpr))
-> Either [Piece v0] (Name TypeExpr)
NB: ‘Piece’ is a non-injective type family
The type variable ‘v0’ is ambiguous
• In the ambiguity check for ‘foldNames'’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature:
foldNames' :: forall m v.
(Monad m, TypeBody v) =>
(Name TypeExpr -> m (Name TypeExpr))
-> Either [Piece v] (Name TypeExpr)
|
135 | :: forall m v. (Monad m, TypeBody v)
class TypeBody v where
varCons :: Name TypeExpr -> v
type Piece v
exprCons :: [Piece v] -> v
toTypeExpr :: v -> TypeExpr
foldNames :: Monad m => (Name TypeExpr -> m (Name TypeExpr)) -> v -> m v
var :: TypeBody v => Identifier -> v
var = varCons . identToName
foldNames'
:: forall m v. (Monad m, TypeBody v)
=> (Name TypeExpr -> m (Name TypeExpr))
-> Either [Piece v] (Name TypeExpr)
foldNames' f (Right v) = varCons <$> f v
-- (the recursion needs to be foldNames, not foldNames')
foldNames' f (Left l) = exprCons <$> forM l (second foldNames f)
instance TypeBody Sum where
varCons :: Name TypeExpr -> Sum
varCons = SumVar
type Piece Sum = (Sign, Product)
exprCons = SumExpr
toTypeExpr = SumTypeExpr
foldNames f (SumVar v) = foldNames' f (Right v)
foldNames f (SumExpr l) = foldNames' f (Left l)
instance TypeBody Product where
varCons :: Name TypeExpr -> Product
varCons = ProductVar
type Piece Product = (Sigil, Sum)
exprCons = ProductExpr
toTypeExpr = ProductTypeExpr
foldNames f (ProductVar v) = foldNames' f (Right v)
foldNames f (ProductExpr l) = foldNames' f (Left l)
data Sign = Pos | Neg
deriving (Read, Show, Ord, Eq, Enum, Bounded, Generic)
instance Alpha Sign
-- like Sign but for if a factor is > or < 1
-- A Sigil is either Gro[w] or Shr[ink]
data Sigil = Gro | Shr
deriving (Read, Show, Ord, Eq, Enum, Bounded, Generic)
instance Alpha Sigil
type VarSet = [Name TypeExpr]
data Product where
ProductVar :: Name TypeExpr -> Product
ProductExpr :: [(Sigil, Sum)] -> Product
deriving (Eq, Show, Generic)
data Sum where
SumVar :: Name TypeExpr -> Sum
SumExpr :: [(Sign, Product)] -> Sum
deriving (Eq, Show, Generic)
data TypeExpr = SumTypeExpr Sum | ProductTypeExpr Product
deriving (Eq, Show, Generic)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment