packages feed

lol-typing-1.20160822: Language/LOL/Typing/Expr/Common.hs

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TupleSections #-}
module Language.LOL.Typing.Expr.Common where

import qualified Data.Foldable as Foldable
import Data.Eq (Eq(..))
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Function (const)
import Data.Functor ((<$>))
import Data.Maybe (Maybe(..))
import Data.Text.Buildable (Buildable(..))

import qualified Language.LOL.Calculus as Calc
import Language.LOL.Typing.Type
import Text.Show

type Name = Text

data TeTy_Var
 =   TeTy_Var_Name Calc.Var_Name
 |   TeTy_Var_Monovar Monovar
 deriving (Eq, Show)
instance Buildable TeTy_Var where
	build x =
		case x of
		 TeTy_Var_Name n -> build n
		 TeTy_Var_Monovar v -> build (Monotype_Var v)

class Calc_Type a where
	calc_type :: a -> Calc.Type TeTy_Var
instance Calc_Type Monotype where
	calc_type ty =
		case app_spine_left ty of
		 Monotype_Var v `App_Spine` [] -> Calc.TeTy_Var (TeTy_Var_Monovar v)
		 Monotype_Const c `App_Spine` [] -> Calc.TeTy_Var (TeTy_Var_Name c)
		 Monotype_Const "->" `App_Spine` [t1, t2] ->
			Calc.Type_Abst (Calc.Suggest "")
			 (calc_type t1)
			 (const Nothing `Calc.abstract` calc_type t2)
		 t `App_Spine` tys ->
			Calc.term_apps
			 (calc_type t)
			 (calc_type <$> tys)
calc_of_polytype
 :: Monoconsts
 -> Polytype
 -> (Monoconsts, Calc.Type TeTy_Var)
calc_of_polytype consts_used Quantification
	 { quantifiers
	 , quantifier_hintnames
	 , quantified } =
	Foldable.foldr
	 (\(quant, qname) ty ->
		let nam = Calc.Suggest qname in
		Calc.Type_Abst nam
		 (Calc.Type_Sort Calc.sort_star_mono)
		 ((\x -> case x of
			 TeTy_Var_Monovar v | v == quant-> Just nam
			 _ -> Nothing) `Calc.abstract` ty)
	 ) (calc_type quantified) <$>
	quantifiers_freshify consts_used quantifier_hintnames quantifiers
calc_abst_term_of_polytype
 :: Monoconsts
 -> Polytype
 -> Calc.Term TeTy_Var
 -> (Monoconsts, Calc.Type TeTy_Var)
calc_abst_term_of_polytype consts_used Quantification
	 { quantifiers
	 , quantifier_hintnames } term =
	Foldable.foldr
	 (\(quant, qname) ty ->
		let nam = Calc.Suggest qname in
		Calc.Term_Abst nam
		 (Calc.Type_Sort Calc.sort_star_mono)
		 ((\x -> case x of
			 TeTy_Var_Monovar v | v == quant -> Just nam
			 _ -> Nothing) `Calc.abstract` ty)
	 ) term <$>
	quantifiers_freshify consts_used quantifier_hintnames quantifiers
{-
instance (Show a, Substitutable a, Buildable (Quantification_Build_Options, a), Calc_Type a)
 => Calc_Type ([Monoconst], Forall a) where
	calc_type (consts_used, f@Quantification
	 { quantifiers
	 , quantifier_hintnames
	 , quantified }) =
		let (_consts_used, quants) = quantifiers_freshify consts_used quantifier_hintnames quantifiers in
		let qty = calc_type quantified in
		Foldable.foldr
		 (\(quant, qname) ty ->
			Calc.Type_Abst (Calc.Suggest qname)
			 (Calc.Type_Sort Calc.sort_star_mono)
			 ((\x ->
				case x of
				 TeTy_Var_Name _ -> Nothing
				 TeTy_Var_Monovar v ->
					if v == quant
					then Just (Calc.Suggest qname)
					else Nothing) `Calc.abstract` ty)
		 ) qty $
		trace ("quants: " <> Build.string (Build.list $ (\(x, y) -> Build.tuple [build x, build y]) <$> quants))
		trace ("forall: " <> Build.string (def::Quantification_Build_Options,f))
		trace ("forall: " <> show f)
		trace ("quantified: " <> show quantified)
		quants
-}
instance (Calc_Type a) => Calc_Type (Qualification [Class_Qualifier] a) where
	calc_type Qualification
	 { qualifiers
	 , qualified } =
		Foldable.foldr
		 (\(Class_Qualifier qname qty) ty ->
			Calc.Term_Abst (Calc.Suggest qname)
			 (calc_type qty)
			 ((\x -> case x of
				 TeTy_Var_Name n | Text.toLower n == qname -> Just (Calc.Suggest qname)
				 _ -> Nothing) `Calc.abstract` ty)
		 ) (calc_type qualified) qualifiers