{- Copyright (C) 2015 Leon Medvinsky This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -} {-| Module : Neet.Training Description : Generic training abstraction Copyright : (c) Leon Medvinsky, 2015 License : GPL-3 Maintainer : lmedvinsky@hotmail.com Stability : experimental Portability : ghc -} module Neet.Training ( Training(..) , trainSingle , trainTraversable ) where import Control.Applicative import qualified Data.Traversable as T import Data.Traversable (Traversable) -- | Training structure. The idea is that if it is 'StillTraining', it is -- presenting you with something that must have its score evaluated, and -- a way to advance the training by providing that score. If it is 'DoneTraining', -- everything has been iterated through. data Training candidate score result = StillTraining candidate (score -> Training candidate score result) | DoneTraining result instance (Show c, Show r) => Show (Training c s r) where show (DoneTraining res) = "DoneTraining " ++ show res show (StillTraining c _) = "StillTraining " ++ show c ++ " <function>" instance Functor (Training candidate score) where fmap f (DoneTraining res) = DoneTraining (f res) fmap f (StillTraining cand k) = StillTraining cand ((fmap . fmap) f k) instance Applicative (Training candidate score) where pure = DoneTraining (<*>) = apTraining apTraining :: Training c s (r1 -> r2) -> Training c s r1 -> Training c s r2 apTraining (DoneTraining f) tcsr1 = fmap f tcsr1 apTraining (StillTraining cand k) tcsr1 = StillTraining cand go where go score = apTraining (k score) tcsr1 trainSingle :: a -> Training a b b trainSingle a = StillTraining a k where k b = DoneTraining b trainTraversable :: Traversable t => t a -> Training a b (t b) trainTraversable = T.traverse trainSingle