thrist 0.1.2 → 0.2
raw patch · 6 files changed
+215/−50 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.Thrist: foldThrist :: (forall i j k. (i ~> j) -> (j ~> k) -> (i ~> k)) -> c ~> c -> Thrist ~> a c -> a ~> c
+ Data.Thrist: Flipped :: m b a -> Flipped m a b
+ Data.Thrist: foldMThrist :: Monad m => (forall j k. (a +> j) -> (j ~> k) -> m (a +> k)) -> (a +> b) -> Thrist ~> b c -> m (a +> c)
+ Data.Thrist: foldl1Thrist :: (forall i j k. (i ~> j) -> (j ~> k) -> (i ~> k)) -> Thrist ~> a b -> (a ~> b)
+ Data.Thrist: foldlThrist :: (forall j k. (a +> j) -> (j ~> k) -> (a +> k)) -> (a +> b) -> Thrist ~> b c -> (a +> c)
+ Data.Thrist: foldr1Thrist :: (forall i j k. (i ~> j) -> (j ~> k) -> (i ~> k)) -> Thrist ~> a b -> (a ~> b)
+ Data.Thrist: foldrThrist :: (forall i j. (i ~> j) -> (j +> c) -> (i +> c)) -> (b +> c) -> Thrist ~> a b -> (a +> c)
+ Data.Thrist: mapMThrist :: Monad m => (forall i j. (i +> j) -> m (i ~> j)) -> Thrist +> a b -> m (Thrist ~> a b)
+ Data.Thrist: newtype Flipped m a b
+ Data.Thrist: nullThrist :: Thrist ~> a b -> Bool
+ Data.Thrist: unflip :: Flipped m a b -> m b a
+ Data.Thrist.List: El :: a -> List a a
+ Data.Thrist.List: data List :: * -> * -> *
+ Data.Thrist.List: instance Monad List'
+ Data.Thrist.Monad: Digest :: (a -> m b) -> Monad' m a b
+ Data.Thrist.Monad: Feed :: m b -> Monad' m a b
+ Data.Thrist.Monad: data Monad' :: (* -> *) -> * -> * -> *
- Data.Thrist: mapThrist :: (forall i j. i +> j -> i ~> j) -> Thrist +> a b -> Thrist ~> a b
+ Data.Thrist: mapThrist :: (forall i j. (i +> j) -> (i ~> j)) -> Thrist +> a b -> Thrist ~> a b
Files
- Data/Thrist.hs +109/−39
- Data/Thrist/List.hs +28/−0
- Data/Thrist/Monad.hs +23/−0
- LICENSE +1/−1
- examples.hs +40/−0
- thrist.cabal +14/−10
Data/Thrist.hs view
@@ -1,57 +1,127 @@-module Data.Thrist ( Thrist (..)- , foldThrist- , appendThrist- , mapThrist ) where+{-# LANGUAGE GADTs, RankNTypes, KindSignatures, FlexibleInstances, TypeOperators #-}+module Data.Thrist ( + -- * Types:+ Thrist (..)+ , Flipped (..)+ -- * Fold and map functions:+ , mapThrist + , foldrThrist+ , foldlThrist+ , foldr1Thrist+ , foldl1Thrist+ -- ** Monadic functions:+ , mapMThrist+ , foldMThrist+ -- * Other list-like functions:+ , appendThrist+ , nullThrist+ ) where -import Prelude-import Data.Monoid+import Prelude hiding ((.), id) import Control.Category--- import Data.Char+import Data.Monoid import Control.Arrow+import Control.Monad ++-- | A type-threaded list of binary polymorphic types. data Thrist :: (* -> * -> *) -> * -> * -> * where Nil :: Thrist (~>) a a Cons :: (a ~> b) -> Thrist (~>) b c -> Thrist (~>) a c +instance Monoid (Thrist (~>) a a) where+ mempty = Nil+ mappend = appendThrist -foldThrist :: (forall i j k . (i ~> j) -> (j ~> k) -> (i ~> k))- -> c ~> c- -> Thrist (~>) a c- -> a ~> c-foldThrist _ v Nil = v-foldThrist f v (Cons h t) = h `f` (foldThrist f v t)+instance Arrow (Thrist (->)) where+ arr f = Cons f Nil+ first Nil = Nil+ first t = Cons ((foldrThrist (flip (.)) id t) *** id) Nil -{- Simple demo:--- MOVE THIS TO TESTS-t1 :: Thrist (->) Char Char-t1 = ord `Cons` ((\i -> i+32) `Cons` (chr `Cons` Nil))+instance Category (Thrist (~>)) where+ id = Nil+ b . a = appendThrist a b -t2 :: Char -> Char-t2 = foldThrist (flip (.)) id t1--} -appendThrist :: forall ((~>) :: * -> * -> *) a b c .- Thrist (~>) a b ->- Thrist (~>) b c ->- Thrist (~>) a c+-- | A newtype wrapper, defined for convenience, that "swaps" the two type+-- variables of a binary type. Can be used to reverse a Thrist using +-- `foldlThrist`. See examples.+newtype Flipped m a b = Flipped { unflip :: m b a } -appendThrist Nil a = a-appendThrist (Cons b r) a = Cons b (appendThrist r a) -mapThrist :: (forall i j . i +> j -> i ~> j) -> Thrist (+>) a b -> Thrist (~>) a b-mapThrist _ Nil = Nil-mapThrist f (Cons a r) = Cons (f a) (mapThrist f r)+-- | Equivalent to `foldr` for thrists. Takes a combining function, a value to+-- replace Nil, and a thrist, returning some new binary type.+foldrThrist :: (forall i j . (i ~> j) -> (j +> c) -> (i +> c)) + -> (b +> c) + -> Thrist (~>) a b + -> (a +> c)+foldrThrist _ v Nil = v+foldrThrist f v (Cons h t) = h `f` (foldrThrist f v t) +-- | Equivalent to (++) for thrists. +appendThrist :: Thrist (~>) a b -> Thrist (~>) b c -> Thrist (~>) a c+appendThrist = flip (foldrThrist Cons) -instance Monoid (Thrist (~>) a a) where- mempty = Nil- mappend = appendThrist+-- | Equivalent to `map` for thrists. Takes a function from one binary type to +-- another and applies it to each thrist element. For example this could +-- convert a thrist of (a,b) into a thrist of Either a b:+mapThrist :: (forall i j . (i +> j) -> (i ~> j)) + -> Thrist (+>) a b + -> Thrist (~>) a b+mapThrist f = foldrThrist (Cons . f) Nil -instance Arrow (Thrist (->)) where- arr f = Cons f Nil- first Nil = Nil- first (t@(Cons _ _)) = Cons ((foldThrist (flip (Prelude..)) Prelude.id t) *** Prelude.id) Nil -instance Category (Thrist (~>)) where- id = Nil- b . a = appendThrist a b+-- | Equivalent to `foldl` for `Thrist`s.+foldlThrist :: (forall j k . (a +> j) -> (j ~> k) -> (a +> k)) + -> (a +> b) + -> Thrist (~>) b c + -> (a +> c)+foldlThrist _ v Nil = v+foldlThrist f v (Cons h t) = foldlThrist f (v `f` h) t ++++-- | Equivalent to `foldl1` for `Thrist`s.+foldl1Thrist :: (forall i j k. (i ~> j) -> (j ~> k) -> (i ~> k))+ -> Thrist (~>) a b+ -> (a ~> b)+foldl1Thrist f (Cons a th) = foldlThrist f a th+foldl1Thrist _ Nil = error "empty thrist"++ ++-- | Equivalent to `foldr1` for `Thrist`s.+foldr1Thrist :: (forall i j k. (i ~> j) -> (j ~> k) -> (i ~> k))+ -> Thrist (~>) a b+ -> (a ~> b)+foldr1Thrist _ (Cons b Nil) = b+foldr1Thrist f (Cons a th) = f a $ foldr1Thrist f th+foldr1Thrist _ Nil = error "empty thrist"++++-- | Equivalent to `mapM` on `Thrist`s. +mapMThrist :: Monad m => + (forall i j . (i +> j) -> m (i ~> j)) + -> Thrist (+>) a b + -> m (Thrist (~>) a b)+mapMThrist _ Nil = return Nil+mapMThrist f (Cons h t) = liftM2 Cons (f h) (mapMThrist f t)+++-- | Equivalent to `foldM` on `Thrist`s.+foldMThrist :: Monad m => + (forall j k . (a +> j) -> (j ~> k) -> m (a +> k)) + -> (a +> b) + -> Thrist (~>) b c + -> m (a +> c)+foldMThrist _ a Nil = return a+foldMThrist f a (Cons h t) = f a h >>= \fah -> foldMThrist f fah t++++-- | Returns `True` when the Thrist is `Nil`.+nullThrist :: Thrist (~>) a b -> Bool+nullThrist Nil = True+nullThrist _ = False+
+ Data/Thrist/List.hs view
@@ -0,0 +1,28 @@+module Data.Thrist.List ( List(..) ) where++import Data.Thrist+import Control.Monad++-- Adapter for creating lists:+-- (Thrist List a a) is isomorphic to [a]++data List :: * -> * -> * where+ El :: a -> List a a++-- It forms a monad+--++newtype List' a = List' (Thrist List a a)++instance Monad List' where+ return a = List' $ Cons (El a) Nil+ List' a >>= f = undefined++{- We need something like:++instance Monad [] where+ m >>= k = foldr ((++) . k) [] m+ m >> k = foldr ((++) . (\ _ -> k)) [] m+ return x = [x]+ fail _ = []+-}
+ Data/Thrist/Monad.hs view
@@ -0,0 +1,23 @@+module Data.Thrist.Monad ( Monad'(..) ) where++-- DISCLAIMER:+-- Highly speculative module, naming, signatures not settled yet!++-- import Data.Thrist+import qualified Control.Monad as CM++-- Adapter for creating monads:+-- (Thrist (Monad' m) a b) is isomorphic to the monadic join : a -> mb++data Monad' :: (* -> *) -> * -> * -> * where+ Feed :: CM.Monad m => m b -> Monad' m a b+ Digest :: CM.Monad m => (a -> m b) -> Monad' m a b++-- It forms a monad -- gosh!+--++{-+instance Monad List' where+ return a = List' $ Cons (El a) Nil+ List' a >>= f = undefined+-}
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2008-2009 Gabor Greif+Copyright (c) 2008-2010 Gabor Greif and Brandon Simmons All rights reserved.
+ examples.hs view
@@ -0,0 +1,40 @@+module Main+ where++-- import the main Thrist module+import Data.Thrist+++-- identity function on thrists in terms of foldrThrist:+idThrist :: Thrist (~>) a c -> Thrist (~>) a c+idThrist = foldrThrist Cons Nil+++ -- Explore creating a reverse function using foldlThrist:+ -- The function takes a Thrist of tuples and reverses it (also swapping the+ -- fst and snd values). We use the Flipped newtype to allow us to pass the+ -- reversed Thrist through the foldl function, and then unwrap it at the end:+reverseTuples :: Thrist (,) a b -> Thrist (,) b a+reverseTuples = unflip . foldlThrist rev (Flipped Nil)+ where rev (Flipped t) (a, b) = Flipped $ Cons (b, a) t+++-- Composing a thrist of functions:+-- Shows one way of composing a thrist of functions (a -> b) using foldl+func :: [(Int, Char)] -> Int+func = foldlThrist (flip(.)) id thristOfFuncs+ -- ...and here is our type-threaded list of functions:+ where thristOfFuncs :: Thrist (->) [(Int, Char)] Int+ thristOfFuncs = Cons head $ Cons fst $ Cons (+2) Nil++ -- type-checker infers Integer here, instead of a polymorphic Num class unless+ -- I explicitly put it in the signature. Is that normal? Interesting?+--funcPoly :: (Num a) => [(a, b)] -> a+funcPoly = foldlThrist (flip(.)) id thristOfFuncs+ where thristOfFuncs :: (Num a) => Thrist (->) [(a, b)] a+ thristOfFuncs = Cons head $ Cons fst $ Cons (+2) Nil+++-- a demo of the `appendThrist` function:+appendedThrists :: (Num a) => Thrist (->) [(a, b)] a+appendedThrists = (Cons head Nil) `appendThrist` (Cons fst Nil) `appendThrist` (Cons (+2) Nil) `appendThrist` Nil
thrist.cabal view
@@ -1,5 +1,5 @@ Name: thrist-Version: 0.1.2+Version: 0.2 Synopsis: Type-threaded list Description:@@ -15,6 +15,9 @@ suitable semantics, function composition (.) can be embedded. .+ Sub-modules demonstrate the power of the thrist+ idea by emulating some familiar data structures.+ . For further ideas, please consult the companion (draft) paper \"Thrists: Dominoes of Data\" at <http://www.opendylan.org/~gabor/Thrist-draft-2008-07-18.pdf>@@ -22,18 +25,19 @@ Category: Data Structures License: BSD3 License-File: LICENSE-Copyright: (c) 2008-2009 Gabor Greif+Copyright: (c) 2008-2010 Gabor Greif and Brandon Simmons -Author: Gabor Greif-Maintainer: ggreif@gmail.com+Author: Gabor Greif, Brandon Simmons+Maintainer: ggreif@gmail.com, brandon.m.simmons@gmail.com Homepage: http://heisenbug.blogspot.com/search/label/thrist Stability: experimental-Build-Depends: base >= 4 && < 5-Extensions: GADTs, RankNTypes, KindSignatures, FlexibleInstances, TypeOperators, FlexibleContexts--Exposed-Modules: Data.Thrist-Ghc-Options: -Wall Cabal-Version: >= 1.2.3-+extra-source-files: examples.hs Build-Type: Simple++library+ Build-Depends: base >= 4 && < 5+ Exposed-Modules: Data.Thrist Data.Thrist.List Data.Thrist.Monad+ Extensions: GADTs, RankNTypes, KindSignatures, FlexibleInstances, TypeOperators, FlexibleContexts+ Ghc-Options: -Wall