packages feed

do-notation-dsl (empty) → 0.1.0.0

raw patch · 16 files changed

+492/−0 lines, 16 filesdep +basedep +containersdep +do-notation-dslsetup-changed

Dependencies added: base, containers, do-notation-dsl, doctest, doctest-discover, temporary

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for dsl++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Yang Bo here (c) 2018++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 Author name here nor the names of other+      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 EVENT SHALL THE COPYRIGHT+OWNER 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.
+ README.md view
@@ -0,0 +1,14 @@+# Dsl++The `Prelude.>>=` combinator limits the return type as a `m b`, which cause Monads not composable. In order to ease this restrictions, this proposal introduces another type class `Dsl` for do notation.++Motivation+----------++Monads do not compose. Normally a `do` block cannot contains operators defined in different monad instances.++The state of art solution is [using only one monad](http://okmij.org/ftp/Haskell/extensible/) `Eff`, which forwards all monadic bind operations to custom effect handlers, instead of defining new monads.++However, the `Eff` approach is heavy weight than ordinary monad. It's not very convenient to create an additional indirect layer for simple use cases.++The  `Eff` approach of bypassing  `>>=` combinator is quite embarrassing. Since  `>>=` settles on our logo, In this proposal we present a new approach to enable multiple operations at once by improving  `>>=`. This proposal aims to port the approach used in [Dsl.scala](https://github.com/ThoughtWorksInc/Dsl.scala) to Haskell. This approach improves the extensibility of `>>=`.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ do-notation-dsl.cabal view
@@ -0,0 +1,63 @@+-- This file has been generated from package.yaml by hpack version 0.28.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: ccaebc69f4e2a90c260f2f0aae7895664f69da64f434fe09d967182f13b83aa2++name:           do-notation-dsl+version:        0.1.0.0+synopsis:       An alternative to monads+description:    Please see the README on GitHub at <https://github.com/Atry/dsl#readme>+category:       Control, DSL, Effect, General, Language, Mutable State, IO, Polymorphism+homepage:       https://github.com/Atry/dsl#readme+bug-reports:    https://github.com/Atry/dsl/issues+author:         Yang Bo+maintainer:     pop.atry@gmail.com+copyright:      2018 Yang Bo+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10+extra-source-files:+    ChangeLog.md+    README.md++source-repository head+  type: git+  location: https://github.com/Atry/dsl++library+  exposed-modules:+      Control.Dsl+      Control.Dsl.Cont+      Control.Dsl.Do+      Control.Dsl.Empty+      Control.Dsl.Monadic+      Control.Dsl.Return+      Control.Dsl.Shift+      Control.Dsl.State+      Control.Dsl.Yield+  other-modules:+      Control.Dsl.Dsl+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+  default-language: Haskell2010++test-suite doctests+  type: exitcode-stdio-1.0+  main-is: doctest-driver.hs+  other-modules:+      Paths_do_notation_dsl+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.7 && <5+    , containers+    , do-notation-dsl+    , doctest+    , doctest-discover+    , temporary+  default-language: Haskell2010
+ src/Control/Dsl.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}++{- |+>>> :set -XTypeFamilies+>>> :set -XMultiParamTypeClasses+>>> :set -XFlexibleInstances+>>> :set -XFlexibleContexts+>>> :set -XRebindableSyntax+>>> :set -XTypeApplications+>>> import qualified Prelude+>>> import Prelude hiding ((>>), (>>=), return)+>>> import Control.Dsl+>>> import Control.Dsl.State+>>> import Control.Dsl.Yield+>>> import Control.Dsl.Return+>>> import Data.Void++>>> :{+f = do+  Yield "foo"+  config <- Get @Bool+  when config $ do+    Yield "bar"+    return ()+  return "baz"+:}++>>> :type f+f :: (Dsl (Yield [Char]) r (), Dsl (Return [Char]) r Void,+      Dsl Get r Bool) =>+     r++>>> f True :: [String]+["foo","bar","baz"]++>>> :{+instance Dsl (Yield String) (IO ()) () where+  cpsApply (Yield a) = (Prelude.>>=) (putStrLn $ "Yield " ++ a)+:}++>>> :{+instance Dsl Get (IO ()) Bool where+  cpsApply Get f = (putStrLn "Get") Prelude.>> f False+:}++>>> :{+instance Dsl (Return String) (IO ()) Void where+  cpsApply (Return a) _ = putStrLn $ "Return " ++ a+:}++>>> f :: IO ()+Yield foo+Get+Return baz+-}+module Control.Dsl(+  module Control.Dsl.Dsl,+  module Control.Dsl.Return,+  module Control.Dsl.Do,+  module Control.Dsl.Cont+) where++import Control.Dsl.Return (return)+import Control.Dsl.Dsl (Dsl(..))+import Control.Dsl.Cont (when)+import Control.Dsl.Do ((>>=), (>>))++-- Import modules that contains orphan instances+import Control.Dsl.Shift ()+-- import Control.Dsl.State ()
+ src/Control/Dsl/Cont.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-}++module Control.Dsl.Cont where++import Prelude hiding ((>>), (>>=), return)++type r !! a = (a -> r) -> r++newtype Cont r a = Cont (r !! a)++when True k = Cont k+when False _ = Cont $ \f -> f ()
+ src/Control/Dsl/Do.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeOperators #-}++module Control.Dsl.Do where++import Control.Dsl.Dsl+import Control.Dsl.Cont+import Prelude hiding ((>>), (>>=), return)++class Do k r a where+  (>>=) :: k r a -> r !! a+  (>>) :: k r a -> r -> r+  k >> a = k >>= const a++instance {-# OVERLAPPABLE #-} Dsl k r a => Do k r a where+  (>>=) = cpsApply++instance Do Cont r a where+  (>>=) (Cont k) = k+
+ src/Control/Dsl/Dsl.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE TypeOperators #-}++module Control.Dsl.Dsl where++import Control.Dsl.Cont+import Control.Applicative+import Data.Void+import Prelude hiding ((>>), (>>=), return)++{- | This type class witnesses a use case of @k@,+which is an ad-hoc delimited continuation adaptive to the answer type @r@.+-}+class Dsl k r a where+  cpsApply :: k r0 a -> r !! a++instance {-# OVERLAPPABLE #-} Dsl k r a => Dsl k (b -> r) a where+  cpsApply k f b = cpsApply k $ \a -> f a b
+ src/Control/Dsl/Empty.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE FunctionalDependencies #-}++module Control.Dsl.Empty where++import Control.Dsl.Dsl+import Data.Void+import Control.Applicative+import Prelude hiding ((>>), (>>=), return)++data Empty r a where+  Empty :: Empty r Void++instance Dsl Empty [r] Void where+  cpsApply Empty _ = []++instance Dsl Empty (Maybe r) Void where+  cpsApply Empty _ = Nothing++empty :: Dsl Empty r Void => r+empty = cpsApply Empty absurd
+ src/Control/Dsl/Monadic.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RebindableSyntax #-}++module Control.Dsl.Monadic where++import Control.Dsl.Dsl+import qualified Prelude++newtype Monadic m r a = Monadic (m a)++instance Prelude.Monad m => Dsl (Monadic m) (m b) a where+  cpsApply (Monadic k) = (Prelude.>>=) k
+ src/Control/Dsl/Return.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE GADTs #-}++module Control.Dsl.Return where++import Prelude hiding ((>>), (>>=), return)+import Control.Dsl.Dsl+import Control.Dsl.Cont+import Control.Exception+import Data.Void++data Return r0 r b where+  Return :: r0 -> Return r0 r Void++instance Dsl (Return r) r Void where+  cpsApply (Return r) _ = r++return r = cpsApply (Return r) absurd++instance Dsl (Return a) (r !! a) Void where+  cpsApply (Return a) _ f = f a++instance Dsl (Return r) [r] Void where+  cpsApply (Return r) _ = [r]++instance Dsl (Return r) (Maybe r) Void where+  cpsApply (Return r) _ = Just r++instance Dsl (Return r) (IO r) Void where+  cpsApply (Return r) _ = evaluate r
+ src/Control/Dsl/Shift.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++{- |+Description : Delimited continuations+-}+module Control.Dsl.Shift where++import Data.Void+import Control.Dsl.Cont+import Control.Dsl.Dsl+import Prelude hiding ((>>), (>>=), return)++{- |+>>> :set -XTypeOperators+>>> :set -XRebindableSyntax+>>> import Prelude hiding ((>>), (>>=), return)+>>> import Control.Dsl+>>> import Control.Dsl.Return+>>> import Control.Dsl.Yield+>>> import Control.Dsl.Empty++>>> :{+earlyGenerator :: Bool -> [String] !! Integer+earlyGenerator earlyReturn = do+  Yield "inside earlyGenerator"+  when earlyReturn $ do+    Yield "early return"+    return 1+  Yield "normal return"+  return 0+:}++>>> :{+earlyGeneratorTest :: [String]+earlyGeneratorTest = do+  Yield "before earlyGenerator"+  i <- Shift $ earlyGenerator True+  Yield "after earlyGenerator"+  Yield $ "the return value of earlyGenerator is " ++ show i+  empty+:}++>>> earlyGeneratorTest+["before earlyGenerator","inside earlyGenerator","early return","after earlyGenerator","the return value of earlyGenerator is 1"]+-}+newtype Shift r0 r a = Shift (r0 !! a)++instance Dsl (Shift r) r a where+  cpsApply (Shift k) f = k f++-- instance Dsl m a d => Dsl m a (Shift d b) where+--   cpsApply k f = Shift $ \g -> cpsApply k $ \a -> cpsApply (f a) g
+ src/Control/Dsl/State.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}++{- |+Description : Mutable variables++This module provides the ability to 'Put' and 'Get' the value of multiple mutable variables in a @do@ block.++>>> :set -XTypeApplications+>>> :set -XRebindableSyntax+>>> import Prelude hiding ((>>), (>>=), return)+>>> import Control.Dsl+>>> import Data.Sequence++>>> :set -fprint-potential-instances+>>> :{+formatter :: Double -> Integer -> Seq String -> String+formatter = do+  --+  -- Equivalent of `!Put(!Get[Vector[Any]] :+ "x=")` in Dsl.scala+  tmpBuffer0 <- Get @(Seq String)+  Put $ tmpBuffer0 |> "x="+  --+  -- Equivalent of `!Put(!Get[Vector[Any]] :+ !Get[Double])` in Dsl.scala+  tmpBuffer1 <- Get @(Seq String)+  d <- Get @Double+  Put $ tmpBuffer1 |> show d+  --+  -- Equivalent of `!Put(!Get[Vector[Any]] :+ ",y=")` in Dsl.scala+  tmpBuffer2 <- Get @(Seq String)+  Put $ tmpBuffer2 |> ",y="+  --+  -- Equivalent of `!Put(!Get[Vector[Any]] :+ !Get[Int])` in Dsl.scala+  tmpBuffer3 <- Get @(Seq String)+  i <- Get @Integer+  Put $ tmpBuffer3 |>  show i+  --+  -- Equivalent of `!Return((!Get[Vector[Any]]).mkString)` in Dsl.scala+  tmpBuffer4 <- Get @(Seq String)+  return $ foldl1 (++) tmpBuffer4+:}++>>> formatter 0.5 42 Empty+"x=0.5,y=42"+-}+module Control.Dsl.State where++import Prelude hiding ((>>), (>>=), return)+import Control.Dsl.Dsl++type State a b = a -> b++data Put a r u where+  Put :: a -> Put a r ()++instance Dsl (Put a) (State a b) () where+  cpsApply (Put a) f _ = f () a++data Get r a where+  Get :: forall a r. Get r a++instance Dsl Get (State a b) a where+  cpsApply Get f a = f a a
+ src/Control/Dsl/Yield.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RebindableSyntax #-}++{- |+Description : Generators++This module contains the 'Yield' data type and related 'Dsl' instances.++The 'Yield' data type can be used to create generators,+similar to the @yield@ keyword in C#, Python, and ECMAScript.++=== Examples++@randomGenerator@ is an example to create+an xorshift pseudo-random number generator+that returns an infinite list of generated numbers.++>>> :set -XTypeApplications+>>> :set -XRebindableSyntax+>>> import Prelude hiding ((>>), (>>=), return)+>>> import Control.Dsl+>>> import Data.Word+>>> import Data.Bits+>>> :{+randomGenerator :: Word32 -> [Word32]+randomGenerator seed =+  do let tmp1 = xor seed $ shiftL seed 13+     let tmp2 = xor tmp1 $ shiftR tmp1 17+     let tmp3 = xor tmp2 $ shiftL tmp2 5+     Yield tmp3+     randomGenerator tmp3+:}++>>> take 5 $ randomGenerator 2463534242+[723471715,2497366906,2064144800,2008045182,3532304609]+-}+module Control.Dsl.Yield where++import Control.Dsl.Dsl++data Yield a r b where+  Yield :: a -> Yield a r ()++instance Dsl (Yield a) [a] () where+  cpsApply (Yield a) f = a : f ()
+ test/doctest-driver.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF doctest-discover #-}