view delta.hs @ 52:69a01cc80075

Define Delta for Infinite changes in Haskell
author Yasutaka Higa <e115763@ie.u-ryukyu.ac.jp>
date Wed, 19 Nov 2014 13:33:37 +0900
parents 8d9c55bac8b2
children 1e6fecb54f1f
line wrap: on
line source

import Control.Applicative
import Data.Numbers.Primes -- $ cabal install primes

type DeltaLog = [String]

data Delta a = Mono DeltaLog a | Delta DeltaLog a (Delta a) deriving Show

logAppend :: DeltaLog -> Delta a -> Delta a
logAppend l (Mono lx x)    = Mono (l ++ lx) x
logAppend l (Delta lx x d) = Delta (l ++ lx) x (logAppend l d)

deltaAppend :: Delta a -> Delta a -> Delta a
deltaAppend (Mono lx x) d = Delta lx x d
deltaAppend (Delta lx x d) ds = Delta lx x (deltaAppend d ds)

firstDelta :: Delta a -> Delta a
firstDelta d@(Mono _ _)   = d
firstDelta (Delta lx x _) = Mono lx x

tailDelta :: Delta a -> Delta a
tailDelta d@(Mono _ _)   = d
tailDelta (Delta _ _ ds) = ds

instance Functor Delta where
    fmap f (Mono lx x)    = Mono  lx (f x)
    fmap f (Delta lx x d) = Delta lx (f x) (fmap f d)

instance Applicative Delta where
    pure f                             = Mono [] f
    (Mono lf f)     <*> (Mono lx x)    = Mono  (lf ++ lx) (f x)
    df@(Mono lf f)  <*> (Delta lx x d) = Delta (lf ++ lx) (f x) (df <*> d)
    (Delta lf f df) <*> d@(Mono lx x)  = Delta (lf ++ lx) (f x) (df <*> d)
    (Delta lf f df) <*> (Delta lx x d) = Delta (lf ++ lx) (f x) (df <*> d)


mu :: Delta (Delta a) -> Delta a
mu (Mono ld d)     = logAppend ld d
mu (Delta ld d ds) = (logAppend ld $ firstDelta d) `deltaAppend` (mu $ fmap tailDelta ds)

instance Monad Delta where
    return x = Mono [] x
    d >>= f  = mu $ fmap f d

returnS :: (Show s) => s -> Delta s
returnS x = Mono [(show x)] x

returnSS :: (Show s) => s -> s -> Delta s
returnSS x y = (returnS x) `deltaAppend` (returnS y)


-- samples

generator :: Int -> Delta [Int]
generator x = let intList = [1..x] in
                  returnS intList

primeFilter :: [Int] -> Delta [Int]
primeFilter xs = let primeList    = filter isPrime xs
                     refactorList = filter even xs    in
                 returnSS primeList refactorList

count :: [Int] -> Delta Int
count xs = let primeCount = length xs in
           returnS primeCount

primeCount :: Int -> Delta Int
primeCount x = generator x >>= primeFilter >>= count

bubbleSort :: [Int] -> Delta [Int]
bubbleSort [] = returnS []
bubbleSort xs = bubbleSort remainValue >>= (\xs -> returnSS (sortedValueL : xs)
                                                            (sortedValueR ++ xs))
    where
        maximumValue = maximum xs
        sortedValueL = maximumValue
        sortedValueR = replicate (length $ filter (== maximumValue) xs) maximumValue
        remainValue  = filter (/= maximumValue) xs