packages feed

hnix-0.14.0: src/Nix/Type/Assumption.hs

-- | Basing on the Nix (Hindley–Milner) type system (that provides decidable type inference):
-- gathering assumptions (inference evidence) about polymorphic types.
{-# LANGUAGE TypeFamilies #-}
module Nix.Type.Assumption
  ( Assumption(..)
  , empty
  , lookup
  , remove
  , extend
  , keys
  , merge
  , mergeAssumptions
  , singleton
  )
where

import           Prelude                 hiding ( Type
                                                , empty
                                                )

import           Nix.Type.Type

newtype Assumption = Assumption { assumptions :: [(Name, Type)] }
  deriving (Eq, Show)

-- We pretend that Assumptions can be inconsistent (nonunique keys),
-- (just like people in real life).
-- The consistency between assumptions is the inference responcibility.
instance Semigroup Assumption where
  (<>) = merge

instance Monoid Assumption where
  mempty = empty

instance One Assumption where
  type OneItem Assumption = (Name, Type)
  one (x, y) = Assumption [(x, y)]

empty :: Assumption
empty = Assumption mempty

extend :: Assumption -> (Name, Type) -> Assumption
extend (Assumption a) (x, s) =
  Assumption $
    (x, s) : a

remove :: Assumption -> Name -> Assumption
remove (Assumption a) var =
  Assumption $
    filter
      (\(n, _) -> n /= var)
      a

lookup :: Name -> Assumption -> [Type]
lookup key (Assumption a) =
  snd <$>
    filter
      (\(n, _) -> n == key)
      a

merge :: Assumption -> Assumption -> Assumption
merge (Assumption a) (Assumption b) =
  Assumption $ a <> b

mergeAssumptions :: [Assumption] -> Assumption
mergeAssumptions = foldl' (<>) mempty

singleton :: Name -> Type -> Assumption
singleton x y = Assumption [(x, y)]

keys :: Assumption -> [Name]
keys (Assumption a) = fst <$> a