packages feed

prototype (empty) → 0.1

raw patch · 4 files changed

+264/−0 lines, 4 filesdep +basedep +monads-tfsetup-changed

Dependencies added: base, monads-tf

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2010, Yoshikuni Jujo+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++  * Redistributions of source code must retain the above copyright notice,+    this list of conditions and the following disclaimer.++  * Redistributions in binary form must reproduce the above copyright+    notice, this list of conditions and the following disclaimer in the+    documentation and/or other materials provided with the distribution.++  * Neither the name of the Yoshikuni Jujo nor the names of its+    contributors may be used to endorse or promote products derived from+    this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVEN SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ prototype.cabal view
@@ -0,0 +1,60 @@+build-type:	Simple+cabal-version:	>= 1.2++name:		prototype+version:	0.1+stability:	experimental+author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>+maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>++license:	BSD3+license-file:	LICENSE++category:	Development+synopsis:	prototype-based programming on Haskell+description:	prototype-based programming on Haskell+		.+		You can download source codes by git.+		.+		git clone git:\/\/github.com\/YoshikuniJujo\/prototype.git prototype+		.+		Example code+		.+		> module Main where+		>+		> import Control.Prototype+		>+		> main :: IO ()+		> main = fmap fst $ flip runPT initPTEnv $ do+		>	dog <- clone object+		>	name <- makeMember "name"+		>	setName <- setMethod dog "setName" $ \this [ n ] -> do+		>		setMember this name n+		>		return [ ]+		>	sit <- setMethod dog "sit" $ \this _ -> do+		>		n <- member this name+		>		liftPT $ putStrLn $ fromPrimStr n ++ " sitting."+		>	myDog <- clone dog+		>	method myDog setName [ primStr "John" ]+		>	method myDog sit [ ]+		>	return ()+		.+		Another sample+		.+		> module Main where+		>+		> import MyToolkit+		>+		> main :: IO ()+		> main = runToolKit $ do+		>	( textView, setText, setContentView ) <- importMyToolkit+		>	myTV <- clone textView+		>	method myTV setText [ primStr "Hello, world!" ]+		>	method myTV setContentView [ ]+		>	return ()++library+  hs-source-dirs:	src+  exposed-modules:	Control.Prototype+  build-depends:	base > 3 && < 5, monads-tf+  ghc-options:		-Wall
+ src/Control/Prototype.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE PackageImports #-}++module Control.Prototype (+	PTMonad,+	Object,+	Member,+	Method,++	runPT,+	initPTEnv,+	object,+	clone,+	makeMember,+	member,+	method,+	setMember,+	setMethod,++	liftPT,+	primInt,+	primStr,+	fromPrimInt,+	fromPrimStr,++	printMemberName,+) where++import "monads-tf" Control.Monad.State+import Data.List+import Data.Maybe++runPT :: Monad m => PTMonad m a -> ObjectEnv m -> m ( a, ObjectEnv m )+runPT = runObject++initPTEnv :: ObjectEnv m+initPTEnv = initObjectEnv++type PTMonad m = ObjectMonad m++type Object = ObjectId+type Member = VarName++liftPT :: Monad m => m a -> ObjectMonad m a+liftPT = lift++makeMember :: Monad m => String -> ObjectMonad m VarName+makeMember = mkVarName++method :: Monad m =>+	ObjectId -> VarName -> [ ObjectId ] -> ObjectMonad m [ ObjectId ]+method = sendMsg++setMethod :: Monad m => ObjectId -> String -> Method m -> ObjectMonad m VarName+setMethod obj mn m = do+	vn <- mkVarName mn+	mt <- mkMethod m+	setVar obj vn mt+	return vn++data ObjectBody m =+	Object {+		objectId	:: ObjectId,+		objectStatus	:: [ ( VarName, ObjectId ) ] } |+	Method {+		objectId :: ObjectId,+		_method :: Method m }++primInt :: Int -> ObjectId+primInt = primitiveInt++primStr :: String -> ObjectId+primStr = primitiveString++fromPrimInt :: ObjectId -> Int+fromPrimInt = fromPrimitiveInt++fromPrimStr :: ObjectId -> String+fromPrimStr = fromPrimitiveString++data ObjectId =+	ObjectId { objectIdInt :: Int	} |+	PrimitiveInt { fromPrimitiveInt :: Int } |+	PrimitiveString { fromPrimitiveString :: String }+	deriving ( Eq, Show )++primitiveInt :: Int -> ObjectId+primitiveInt = PrimitiveInt++primitiveString :: String -> ObjectId+primitiveString = PrimitiveString++type Method m = ObjectId -> [ ObjectId ] -> ObjectMonad m [ ObjectId ]++object :: ObjectId+object = ObjectId 0++initObject :: ObjectBody m+initObject = Object object [ ]++instance Show ( ObjectBody m ) where+	show Method { }		= "method"+	show ( Object oid st )	= "Object " ++ show oid ++ " " ++ show st+data VarName = VarName String deriving ( Eq, Show )++printMemberName :: MonadIO m => VarName -> m ()+printMemberName = printVarName+printVarName :: MonadIO m => VarName -> m ()+printVarName ( VarName vn ) = liftIO $ putStrLn vn++type ObjectMonad m = StateT ( ObjectEnv m ) m++type ObjectEnv m = [ ObjectBody m ]++initObjectEnv :: ObjectEnv m+initObjectEnv = [ initObject ]++runObject :: Monad m => ObjectMonad m a -> ObjectEnv m -> m ( a, ObjectEnv m )+runObject = runStateT++getObject :: Monad m => ObjectId -> ObjectMonad m ( ObjectBody m )+getObject obj = do+	ret <- gets ( hd . filter ( ( == obj ) . objectId ) )+	case ret of+		Nothing -> get >>= error . show+		Just x -> return x+	where+	hd [ ] = Nothing+	hd xs = Just $ head xs++putObject :: Monad m => ObjectBody m -> ObjectMonad m ()+putObject = modify . ( : )++getNewId :: Monad m => ObjectMonad m ObjectId+getNewId = do+	ids <- gets $ map ( objectIdInt . objectId )+	return $ ObjectId $ head $ [ 1 .. ] \\ ids++clone :: Monad m => ObjectId -> ObjectMonad m ObjectId+clone obj = do+	st <- getObject obj >>= return . objectStatus+	newId <- getNewId+	putObject $ Object newId st+	return newId++mkVarName :: Monad m => String -> ObjectMonad m VarName+mkVarName = return . VarName++setMember :: Monad m => ObjectId -> VarName -> ObjectId -> ObjectMonad m ()+setMember = setVar++setVar :: Monad m => ObjectId -> VarName -> ObjectId -> ObjectMonad m ()+setVar obj vn val = do+	st <- getObject obj >>= return . objectStatus+	putObject $ Object obj $ ( vn, val ) : st++member :: Monad m => ObjectId -> VarName -> ObjectMonad m ObjectId+member = getVar+getVar :: Monad m => ObjectId -> VarName -> ObjectMonad m ObjectId+getVar obj vn = do+	st <- getObject obj >>= return . objectStatus+	return $ fromJust $ lookup vn st++mkMethod :: Monad m => Method m -> ObjectMonad m ObjectId+mkMethod m = do+	newId <- getNewId+	putObject $ Method newId m+	return newId++sendMsg :: Monad m =>+	ObjectId -> VarName -> [ ObjectId ] -> ObjectMonad m [ ObjectId ]+sendMsg obj mn args = do+	Object { objectStatus = vs } <- getObject obj+	let	mt = fromJust $ lookup mn vs+	Method _ m <- getObject mt+	m obj args