WIP evaluation of Lamda Individuals
This commit is contained in:
		
							parent
							
								
									aea502ad64
								
							
						
					
					
						commit
						a4012804fb
					
				
							
								
								
									
										29
									
								
								haga.cabal
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								haga.cabal
									
									
									
									
									
								
							@ -21,21 +21,24 @@ build-type:          Simple
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
library
 | 
					library
 | 
				
			||||||
  build-depends:       base
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
                     , cassava
 | 
					                     , cassava
 | 
				
			||||||
                     , containers
 | 
					                     , containers
 | 
				
			||||||
                     , extra
 | 
					                     , extra
 | 
				
			||||||
                     , MonadRandom
 | 
					                     , hint
 | 
				
			||||||
                     , monad-loops
 | 
					                     , monad-loops
 | 
				
			||||||
 | 
					                     , MonadRandom
 | 
				
			||||||
 | 
					                     , mwc-random
 | 
				
			||||||
                     , optparse-applicative
 | 
					                     , optparse-applicative
 | 
				
			||||||
 | 
					                     , path
 | 
				
			||||||
                     , pipes
 | 
					                     , pipes
 | 
				
			||||||
 | 
					                     , primitive
 | 
				
			||||||
                     , protolude
 | 
					                     , protolude
 | 
				
			||||||
                     , QuickCheck
 | 
					                     , QuickCheck
 | 
				
			||||||
                     , quickcheck-instances
 | 
					                     , quickcheck-instances
 | 
				
			||||||
                     , random
 | 
					                     , random
 | 
				
			||||||
                     , random-fu
 | 
					                     , random-fu
 | 
				
			||||||
                     , random-shuffle
 | 
					                     , random-shuffle
 | 
				
			||||||
                     , mwc-random
 | 
					 | 
				
			||||||
                     , primitive
 | 
					 | 
				
			||||||
                     , text
 | 
					                     , text
 | 
				
			||||||
                     , wl-pprint-text
 | 
					                     , wl-pprint-text
 | 
				
			||||||
  default-language:    Haskell2010
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
@ -49,21 +52,24 @@ library
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
executable haga
 | 
					executable haga
 | 
				
			||||||
  build-depends:       base
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
                     , cassava
 | 
					                     , cassava
 | 
				
			||||||
                     , containers
 | 
					                     , containers
 | 
				
			||||||
                     , extra
 | 
					                     , extra
 | 
				
			||||||
                     , MonadRandom
 | 
					                     , hint
 | 
				
			||||||
                     , monad-loops
 | 
					                     , monad-loops
 | 
				
			||||||
 | 
					                     , MonadRandom
 | 
				
			||||||
 | 
					                     , mwc-random
 | 
				
			||||||
                     , optparse-applicative
 | 
					                     , optparse-applicative
 | 
				
			||||||
 | 
					                     , path
 | 
				
			||||||
                     , pipes
 | 
					                     , pipes
 | 
				
			||||||
 | 
					                     , primitive
 | 
				
			||||||
                     , protolude
 | 
					                     , protolude
 | 
				
			||||||
                     , QuickCheck
 | 
					                     , QuickCheck
 | 
				
			||||||
                     , quickcheck-instances
 | 
					                     , quickcheck-instances
 | 
				
			||||||
                     , random
 | 
					                     , random
 | 
				
			||||||
                     , random-fu
 | 
					                     , random-fu
 | 
				
			||||||
                     , random-shuffle
 | 
					                     , random-shuffle
 | 
				
			||||||
                     , mwc-random
 | 
					 | 
				
			||||||
                     , primitive
 | 
					 | 
				
			||||||
                     , text
 | 
					                     , text
 | 
				
			||||||
                     , wl-pprint-text
 | 
					                     , wl-pprint-text
 | 
				
			||||||
  default-language:    Haskell2010
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
@ -78,22 +84,25 @@ executable haga
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
executable haga-test
 | 
					executable haga-test
 | 
				
			||||||
  build-depends:       base
 | 
					  build-depends:       base
 | 
				
			||||||
 | 
					                     , bytestring
 | 
				
			||||||
 | 
					                     , Cabal
 | 
				
			||||||
                     , cassava
 | 
					                     , cassava
 | 
				
			||||||
                     , containers
 | 
					                     , containers
 | 
				
			||||||
                     , Cabal
 | 
					 | 
				
			||||||
                     , extra
 | 
					                     , extra
 | 
				
			||||||
                     , MonadRandom
 | 
					                     , hint
 | 
				
			||||||
                     , monad-loops
 | 
					                     , monad-loops
 | 
				
			||||||
 | 
					                     , MonadRandom
 | 
				
			||||||
 | 
					                     , mwc-random
 | 
				
			||||||
                     , optparse-applicative
 | 
					                     , optparse-applicative
 | 
				
			||||||
 | 
					                     , path
 | 
				
			||||||
                     , pipes
 | 
					                     , pipes
 | 
				
			||||||
 | 
					                     , primitive
 | 
				
			||||||
                     , protolude
 | 
					                     , protolude
 | 
				
			||||||
                     , QuickCheck
 | 
					                     , QuickCheck
 | 
				
			||||||
                     , quickcheck-instances
 | 
					                     , quickcheck-instances
 | 
				
			||||||
                     , random
 | 
					                     , random
 | 
				
			||||||
                     , random-fu
 | 
					                     , random-fu
 | 
				
			||||||
                     , random-shuffle
 | 
					                     , random-shuffle
 | 
				
			||||||
                     , mwc-random
 | 
					 | 
				
			||||||
                     , primitive
 | 
					 | 
				
			||||||
                     , text
 | 
					                     , text
 | 
				
			||||||
                     , wl-pprint-text
 | 
					                     , wl-pprint-text
 | 
				
			||||||
  default-language:    Haskell2010
 | 
					  default-language:    Haskell2010
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										15
									
								
								src/GA.hs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/GA.hs
									
									
									
									
									
								
							@ -19,10 +19,11 @@
 | 
				
			|||||||
-- In order to use it for a certain problem, basically, you have to make your
 | 
					-- In order to use it for a certain problem, basically, you have to make your
 | 
				
			||||||
-- solution type an instance of 'Individual' and then simply call the 'run'
 | 
					-- solution type an instance of 'Individual' and then simply call the 'run'
 | 
				
			||||||
-- function.
 | 
					-- function.
 | 
				
			||||||
module GA ( Environment,new, population, mutate, crossover1,crossover, Evaluator, fitness,  Individual, GA.run, tournament, N, R, Population, steps, bests, runTests) where
 | 
					module GA ( Environment,new, population, mutate, crossover1,crossover, Evaluator, fitness, calc, Individual, GA.run, tournament, N, R, Population, steps, bests, runTests) where
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Control.Arrow hiding (first, second)
 | 
					import Control.Arrow hiding (first, second)
 | 
				
			||||||
import Data.List.NonEmpty ((<|))
 | 
					import Data.List.NonEmpty ((<|))
 | 
				
			||||||
 | 
					import qualified Data.Map.Strict as Map
 | 
				
			||||||
import qualified Data.List.NonEmpty as NE
 | 
					import qualified Data.List.NonEmpty as NE
 | 
				
			||||||
import qualified Data.List.NonEmpty.Extra as NE (appendl)
 | 
					import qualified Data.List.NonEmpty.Extra as NE (appendl)
 | 
				
			||||||
import Data.Random
 | 
					import Data.Random
 | 
				
			||||||
@ -81,7 +82,7 @@ class (Pretty e, Individual i) => Environment i e where
 | 
				
			|||||||
--  An Evaluator that Individuals of type i can be evaluated by
 | 
					--  An Evaluator that Individuals of type i can be evaluated by
 | 
				
			||||||
--  It stores all information required to evaluate an individuals fitness
 | 
					--  It stores all information required to evaluate an individuals fitness
 | 
				
			||||||
--
 | 
					--
 | 
				
			||||||
class (Eq e, Individual i) => Evaluator i e where
 | 
					class (Individual i) => Evaluator i e where
 | 
				
			||||||
  -- |
 | 
					  -- |
 | 
				
			||||||
  --  An individual's fitness. Higher values are considered “better”.
 | 
					  --  An individual's fitness. Higher values are considered “better”.
 | 
				
			||||||
  --
 | 
					  --
 | 
				
			||||||
@ -89,7 +90,13 @@ class (Eq e, Individual i) => Evaluator i e where
 | 
				
			|||||||
  --  'proportionate1').
 | 
					  --  'proportionate1').
 | 
				
			||||||
  fitness :: e -> i -> R
 | 
					  fitness :: e -> i -> R
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class (Pretty i, Eq i) => Individual i
 | 
					  -- TODO kinda hacky?!?
 | 
				
			||||||
 | 
					  calc :: e ->  Population i -> IO e
 | 
				
			||||||
 | 
					  calc eval _ = do
 | 
				
			||||||
 | 
					    return eval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class (Pretty i, Ord i) => Individual i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -183,6 +190,8 @@ stepSteady eval env select nParents nX pElite pop = do
 | 
				
			|||||||
  iParents <- select nParents pop
 | 
					  iParents <- select nParents pop
 | 
				
			||||||
  iChildren <- NE.filter (`notElem` pop) <$> children env nX iParents
 | 
					  iChildren <- NE.filter (`notElem` pop) <$> children env nX iParents
 | 
				
			||||||
  let pop' = pop `NE.appendl` iChildren
 | 
					  let pop' = pop `NE.appendl` iChildren
 | 
				
			||||||
 | 
					  -- TODO kinda hacky?!?
 | 
				
			||||||
 | 
					  eval <- liftIO $ calc eval pop'
 | 
				
			||||||
  let eliteSize = floor . (pElite *) . fromIntegral $ NE.length pop
 | 
					  let eliteSize = floor . (pElite *) . fromIntegral $ NE.length pop
 | 
				
			||||||
  let (elitists, rest) = bests eval eliteSize pop'
 | 
					  let (elitists, rest) = bests eval eliteSize pop'
 | 
				
			||||||
  case rest of
 | 
					  case rest of
 | 
				
			||||||
 | 
				
			|||||||
@ -15,6 +15,9 @@ import qualified Data.List.NonEmpty as NE
 | 
				
			|||||||
import qualified Data.Map.Strict as Map
 | 
					import qualified Data.Map.Strict as Map
 | 
				
			||||||
import Data.Maybe
 | 
					import Data.Maybe
 | 
				
			||||||
import Data.Random
 | 
					import Data.Random
 | 
				
			||||||
 | 
					import qualified Data.ByteString.Lazy as B
 | 
				
			||||||
 | 
					import Data.Csv
 | 
				
			||||||
 | 
					import Data.Proxy
 | 
				
			||||||
import qualified Data.Text as T
 | 
					import qualified Data.Text as T
 | 
				
			||||||
import Data.Typeable
 | 
					import Data.Typeable
 | 
				
			||||||
import GA
 | 
					import GA
 | 
				
			||||||
@ -23,6 +26,7 @@ import Protolude
 | 
				
			|||||||
import Test.QuickCheck hiding (sample, shuffle)
 | 
					import Test.QuickCheck hiding (sample, shuffle)
 | 
				
			||||||
import Test.QuickCheck.Monadic (assert, monadicIO)
 | 
					import Test.QuickCheck.Monadic (assert, monadicIO)
 | 
				
			||||||
import qualified Type.Reflection as Ref
 | 
					import qualified Type.Reflection as Ref
 | 
				
			||||||
 | 
					import qualified Language.Haskell.Interpreter as Hint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data ExpressionWeights = ExpressionWeights
 | 
					data ExpressionWeights = ExpressionWeights
 | 
				
			||||||
  { lambdaSpucker :: Int,
 | 
					  { lambdaSpucker :: Int,
 | 
				
			||||||
@ -40,6 +44,18 @@ data LambdaEnviroment = LambdaEnviroment
 | 
				
			|||||||
    weights :: ExpressionWeights
 | 
					    weights :: ExpressionWeights
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data LamdaExecutionEnv = LamdaExecutionEnv {
 | 
				
			||||||
 | 
					    -- For now these need to define all available functions and types. Generic functions can be used.
 | 
				
			||||||
 | 
					    imports :: [Text],
 | 
				
			||||||
 | 
					    --Path to a CSV file containing the training dataset
 | 
				
			||||||
 | 
					    trainingDataset :: FilePath,
 | 
				
			||||||
 | 
					    --Path to a CSV file containing the dataset results
 | 
				
			||||||
 | 
					    trainingDatasetRes :: FilePath,
 | 
				
			||||||
 | 
					    exTargetType :: TypeRep,
 | 
				
			||||||
 | 
					    -- todo: kindaHacky
 | 
				
			||||||
 | 
					    results :: Map TypeRequester R
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
showSanifid:: Show a => a -> Text
 | 
					showSanifid:: Show a => a -> Text
 | 
				
			||||||
showSanifid var = T.replace " -> " "To" (show var)
 | 
					showSanifid var = T.replace " -> " "To" (show var)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -76,7 +92,7 @@ type ConVal = Text
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
-- LambdaSpucker - adds TypeRequester#1 as bound var and returns the result of TypeRequester#2
 | 
					-- LambdaSpucker - adds TypeRequester#1 as bound var and returns the result of TypeRequester#2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int [TypeRequester] BoundVars | Constan ConVal deriving (Eq)
 | 
					data LambdaExpression = LambdaSpucker TypeRequester TypeRequester BoundVars | LambdaSchlucker TypeRequester BoundVars | Symbol ConVal [TypeRequester] BoundVars | Var TypeRep Int [TypeRequester] BoundVars | Constan ConVal deriving (Eq, Ord)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
asList :: LambdaExpression -> [TypeRequester]
 | 
					asList :: LambdaExpression -> [TypeRequester]
 | 
				
			||||||
asList (LambdaSpucker tr1 tr2 _) = [tr1, tr2]
 | 
					asList (LambdaSpucker tr1 tr2 _) = [tr1, tr2]
 | 
				
			||||||
@ -87,7 +103,7 @@ asList (Constan _) = []
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
data TypeRequester = TR TypeRep (Maybe LambdaExpression) BoundVars deriving (Eq)
 | 
					data TypeRequester = TR TypeRep (Maybe LambdaExpression) BoundVars deriving (Eq, Ord)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
toLambdaExpressionS :: TypeRequester -> Text
 | 
					toLambdaExpressionS :: TypeRequester -> Text
 | 
				
			||||||
toLambdaExpressionS (TR typeRep (Just lambdaExpression) boundVars) = "((" <> eToLambdaExpressionS lambdaExpression <> ") :: (" <> show typeRep <> "))"
 | 
					toLambdaExpressionS (TR typeRep (Just lambdaExpression) boundVars) = "((" <> eToLambdaExpressionS lambdaExpression <> ") :: (" <> show typeRep <> "))"
 | 
				
			||||||
@ -226,48 +242,69 @@ genLambdaVar' tr varType varNumber trs env@(LambdaEnviroment functions constants
 | 
				
			|||||||
      ret <- genLambdaVar' rest varType varNumber (trs ++ [newTypeRequ]) env depthLeft target boundVar
 | 
					      ret <- genLambdaVar' rest varType varNumber (trs ++ [newTypeRequ]) env depthLeft target boundVar
 | 
				
			||||||
      return ret
 | 
					      return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
instance Environment TypeRequester LambdaEnviroment where
 | 
					instance Environment TypeRequester LambdaEnviroment where
 | 
				
			||||||
new env@(LambdaEnviroment _ _ target maxDepth _) = do
 | 
					  new env@(LambdaEnviroment _ _ target maxDepth _) = do
 | 
				
			||||||
    tr <- genTypeRequester env maxDepth target []
 | 
					    tr <- genTypeRequester env maxDepth target []
 | 
				
			||||||
    return tr
 | 
					    return tr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mutate env@(LambdaEnviroment _ _ _ maxDepth _) tr = do
 | 
					  mutate env@(LambdaEnviroment _ _ _ maxDepth _) tr = do
 | 
				
			||||||
    let trCount = countTrsR(tr)
 | 
					    let trCount = countTrsR(tr)
 | 
				
			||||||
    selectedTR <- uniform 1 trCount
 | 
					    selectedTR <- uniform 1 trCount
 | 
				
			||||||
    let (depthAt,(TR trep _ bound)) = depthLeftAndTypeAtR tr selectedTR maxDepth
 | 
					    let (depthAt,(TR trep _ bound)) = depthLeftAndTypeAtR tr selectedTR maxDepth
 | 
				
			||||||
    res <- genTypeRequester env depthAt trep bound
 | 
					    res <- genTypeRequester env depthAt trep bound
 | 
				
			||||||
    return $ replaceAtR selectedTR tr res
 | 
					    return $ replaceAtR selectedTR tr res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
crossover1 env@(LambdaEnviroment _ _ _ maxDepth _) tr1 tr2 = do
 | 
					  crossover1 env@(LambdaEnviroment _ _ _ maxDepth _) tr1 tr2 = do
 | 
				
			||||||
  let trCount = countTrsR tr1
 | 
					    return Nothing
 | 
				
			||||||
  selectedIndex1 <- uniform 1 trCount
 | 
					 | 
				
			||||||
  let (depthAt, selectedTr1@(TR trep _ bound)) = depthLeftAndTypeAtR tr selectedTR maxDepth
 | 
					 | 
				
			||||||
  let indexes = findIndicesWhere tr2 ( == trep)
 | 
					 | 
				
			||||||
  if length indexes == 0 then return Nothing else (do
 | 
					 | 
				
			||||||
    (selectedTr2,selectedIndex2) <- randomElement indexes
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instance Evaluator TypeRequester LamdaExecutionEnv where
 | 
				
			||||||
 | 
					  fitness env tr = (results env) Map.! tr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  calc env pop = do
 | 
				
			||||||
 | 
					    let toAdd = NE.filter (\k -> Map.member k (results env) ) pop
 | 
				
			||||||
 | 
					    let insertPair (key, val) m = Map.insert key val m
 | 
				
			||||||
 | 
					    toInsert <- Hint.runInterpreter (evalResults env toAdd)
 | 
				
			||||||
 | 
					    let res = foldr insertPair (results env) (fromRight undefined toInsert)
 | 
				
			||||||
 | 
					    return env {results = res}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--  let trCount = countTrsR tr1
 | 
				
			||||||
 | 
					--  selectedIndex1 <- uniform 1 trCount
 | 
				
			||||||
 | 
					--  let (depthAt, selectedTr1@(TR trep _ bound)) = depthLeftAndTypeAtR tr selectedTR maxDepth
 | 
				
			||||||
 | 
					--  let indexes = findIndicesWhere tr2 ( == trep)
 | 
				
			||||||
 | 
					--  if length indexes == 0 then return Nothing else (do
 | 
				
			||||||
 | 
					--    (selectedTr2,selectedIndex2) <- randomElement indexes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    )
 | 
					evalResults :: LamdaExecutionEnv -> [TypeRequester] -> Hint.InterpreterT IO [(TypeRequester, R)]
 | 
				
			||||||
 | 
					evalResults ex trs = mapM (evalResult ex) trs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					data IrisClass = Setosa | Virginica | Versicolor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					evalResult :: LamdaExecutionEnv -> TypeRequester -> Hint.InterpreterT IO (TypeRequester, R)
 | 
				
			||||||
 | 
					evalResult ex tr = do
 | 
				
			||||||
 | 
					  Hint.loadModules (map show (imports ex))
 | 
				
			||||||
 | 
					  result <- Hint.interpret (show (toLambdaExpressionS tr)) (Hint.as ::R -> R -> R -> IrisClass)
 | 
				
			||||||
 | 
					  csv <- liftIO $ B.readFile (trainingDataset ex)
 | 
				
			||||||
 | 
					  let recs = toList $ fromRight undefined $ decode NoHeader csv
 | 
				
			||||||
 | 
					  let res = map (show (uncurry result)) recs
 | 
				
			||||||
 | 
					  csvRes <- liftIO $ B.readFile (trainingDatasetRes ex)
 | 
				
			||||||
 | 
					  let recsRes = toList $ fromRight undefined $ decode NoHeader csvRes
 | 
				
			||||||
 | 
					  let score = (foldr (\ts s -> if fst ts == snd ts then s + 1 else s - 1) 0 (zip recsRes res)) :: R
 | 
				
			||||||
 | 
					  return (tr, score)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- helper
 | 
					-- helper
 | 
				
			||||||
findIndicesWhere:: TypeRequester -> (TypeRep -> Bool) -> Int -> [(TypeRequester, Int)]
 | 
					--findIndicesWhere:: TypeRequester -> (TypeRep -> Bool) -> Int -> [(TypeRequester, Int)]
 | 
				
			||||||
findIndicesWhere tr@(TR t lE _) filte indx = case lE of
 | 
					--findIndicesWhere tr@(TR t lE _) filte indx = case lE of
 | 
				
			||||||
                            Just le -> (tr, indx+1):(findIndicesWhere' (asList le) filte (indx+1))
 | 
					--                            Just le -> (tr, indx+1):(findIndicesWhere' (asList le) filte (indx+1))
 | 
				
			||||||
                            Nothing -> undefined
 | 
					--                            Nothing -> undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
findIndicesWhere':: [TypeRequester] -> (TypeRep -> Bool) -> Int -> [(TypeRequester, Int)]
 | 
					--findIndicesWhere':: [TypeRequester] -> (TypeRep -> Bool) -> Int -> [(TypeRequester, Int)]
 | 
				
			||||||
findIndicesWhere' (tr:trs) f indx = (findIndicesWhere tr f indx) ++ (findIndicesWhere' trs f (indx + countTrsR tr))
 | 
					--findIndicesWhere' (tr:trs) f indx = (findIndicesWhere tr f indx) ++ (findIndicesWhere' trs f (indx + countTrsR tr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
depthLeftAndTypeInSubtreeWithIndex :: [TypeRequester] -> Int -> Int -> (Int, TypeRequester)
 | 
					 | 
				
			||||||
depthLeftAndTypeInSubtreeWithIndex (tr:trs) indexLeft depthLeft = if countTrsR tr >= indexLeft then depthLeftAndTypeAtR tr indexLeft depthLeft else depthLeftAndTypeInSubtreeWithIndex trs (indexLeft - countTrsR tr) depthLeft
 | 
					 | 
				
			||||||
depthLeftAndTypeInSubtreeWithIndex [] indexLeft depthLeft = undefined
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
replaceAtR:: Int -> TypeRequester -> TypeRequester -> TypeRequester
 | 
					replaceAtR:: Int -> TypeRequester -> TypeRequester -> TypeRequester
 | 
				
			||||||
replaceAtR 0 _ with = with
 | 
					replaceAtR 0 _ with = with
 | 
				
			||||||
replaceAtR i (TR tm (Just le) bV) with = TR tm (Just (replaceAt (i-1) le with)) bV
 | 
					replaceAtR i (TR tm (Just le) bV) with = TR tm (Just (replaceAt (i-1) le with)) bV
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user