----------------------------------------------------------------------------- -- Copyright : (c) Hanzhong Xu, Meng Meng 2016, -- License : MIT License -- -- Maintainer : hanzh.xu@gmail.com -- Stability : experimental -- Portability : portable ----------------------------------------------------------------------------- -- HelloWorld ----------------------------------------------------------------------------- {-# LANGUAGE PartialTypeSignatures #-} module HelloWorld where import Control.AFSM import Control.AFSM.SMH import Data.Maybe -- | x_i donates the ith element of the input, y_i donates the ith element of the output. -- $setup -- >>> let test0 = [1,2,3,4]::[Int] -- basic machines -- | the sum of the history, y_n = \sum_{i=1}^n x_i -- >>> smfmap sumSM test0 -- [1,3,6,10] sumSM :: SM Int Int Int sumSM = simpleSM (\s a -> (s+a, s+a)) 0 -- | y_n = x_n + 1 -- >>> smfmap plusOneSM test0 -- [2,3,4,5] plusOneSM :: SM () Int Int plusOneSM = simpleSM (\() a -> ((), a + 1)) () -- | y_n = x_n * 2 -- >>> smfmap timesTwoSM test0 -- [2,4,6,8] timesTwoSM :: SM () Int Int timesTwoSM = arrSM (\a -> a * 2) -- combination machine -- | y_n = \sum_{i=1}^n x_i * 2 -- >>> smfmap ttSM test0 -- [2,6,12,20] ttSM = timesTwoSM >>>> sumSM -- | y_n = (x_n + 1, x_n * 2) -- >>> smfmap ptSM test0 -- [(2,2),(3,4),(4,6),(5,8)] ptSM = plusOneSM &&&& timesTwoSM -- | -- >>> smfmap mergeOutSM [(2,2),(3,4),(4,6),(5,8)] -- [4,7,10,13] -- -- | y_n = (x_n + 1) + (x_n * 2) -- >>> smfmap ((plusOneSM &&&& timesTwoSM) >>>> mergeOutSM) test0 -- [4,7,10,13] mergeOutSM :: SM () (Int, Int) Int mergeOutSM = arrSM (\(a,b)->a+b) -- example 3 data StackOP = Push Int | Pop | Max deriving Show pushStk [] a = ([a], a) pushStk s a = (a:s, a) popStk [] = ([], 0) popStk (x:xs) = (xs, x) maxStk [] = ([], 0) maxStk s = (s, maxList s) maxList :: [Int] -> Int maxList [] = 0 maxList (x:xs) = max x (maxList xs) initial = [] {- pushStk ([],[]) a = (([a],[a]), a) pushStk ((x:xs), (y:ys)) a = if a >= y then ((a:x:xs, a:y:ys), a) else ((a:x:xs, y:ys), a) popStk ([],[]) = (([],[]), 0) popStk ((x:xs), (y:ys)) = if x == y then ((xs, ys), x) else ((xs, y:ys), x) maxStk ([], []) = (([], []), 0) maxStk ((x:xs), (y:ys)) = (((x:xs), (y:ys)), y) initial = ([],[]) -} sf s (Push a) = pushStk s a sf s Pop = popStk s sf s Max = maxStk s -- | The stroage type is changing during switching the implementation. -- There are three ways to handle this issue, -- 1. Remove the type signature of maxSM -- 2. Use hideStorage to hide the storage type -- 3. Use the PartialTypeSignatures extension, leave a hole in the type signature. -- Personaly, I prefer to use the third one, -- because the input type and output type are decidable. -- >>> smfmap maxSM [Push 5, Push 3, Push 2, Max, Push 7, Max, Pop, Max] -- [5,3,2,5,7,7,7,5] maxSM :: SM _ StackOP Int maxSM = simpleSM sf initial -- maxSM :: SM () StackOP Int -- maxSM = hideStorage $ simpleSM sf initial