lambdabot-4.0: scripts/hoogle/src/Hoogle/TypeAlias.hs
{-
This file is part of Hoogle, (c) Neil Mitchell 2004-2005
http://www.cs.york.ac.uk/~ndm/hoogle/
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
-}
{-|
Deal with type aliases, i.e. type String = [Char]
-}
module Hoogle.TypeAlias(
AliasTable,
buildAlias,
lookupAlias,
showAliasTable
) where
import Hoogle.TypeSig
import qualified Data.Map as Map
import Data.Maybe
-- | Alias is a string, being the name of the constructor
-- the number of arguments it takes, and the resulting type
-- TNum is used for replacement positions
data AliasTable = AliasTable (Map.Map String (Int, Type))
deriving Show
-- | Given a list of aliases, build an alias table
-- All members of Item must be TypeAlias
buildAlias :: [Item] -> AliasTable
buildAlias xs = {- AliasTable $ Map.fromList $ -} fixpAlias $ map f xs
where
f (TypeAlias name args ([], typ)) =
(name, (length args, mapUnbound (g (zip args [0..])) typ))
g lst name = case lookup name lst of
Just n -> TNum n
Nothing -> TVar name
-- yay for circular programming
-- boo for possible non-termination
fixpAlias :: [(String, (Int, Type))] -> AliasTable
fixpAlias x = map2
where
map2 = AliasTable $ Map.map (\(a,b) -> (a, lookupAlias map2 b)) map1
map1 = Map.fromList x
-- | Given a type, follow all aliases to find the ultimate one
lookupAlias :: AliasTable -> Type -> Type
lookupAlias (AliasTable table) (TLit x) = typ
where (0, typ) = Map.findWithDefault (0, TLit x) x table
lookupAlias a@(AliasTable table) (TList (TLit x:xs)) = if isJust res then some else none
where
res = Map.lookup x table
none = TList (TLit x : map (lookupAlias a) xs)
Just (n, typ) = res
some = if n == length xs
then mapNumber (xs !!) typ
else error "lookupAlias: mismatch"
lookupAlias _ x = x
showAliasTable :: AliasTable -> String
showAliasTable (AliasTable x) = unlines $ map showAlias (Map.toList x)
showAlias (name, (args, typ)) = "type " ++ name ++ "[" ++ show args ++ "] = " ++ show typ