The open-union package

[Tags: library, mit, program]

Extensible, type-safe unions. This package is very new and likely to change.

Basic usage example (language tags ommitted due to https://github.com/haskell/cabal/issues/774)

 import Data.OpenUnion
 type MyUnion = Union '[Char, Int, [()]]
 showMyUnion :: MyUnion -> String
 showMyUnion
     =  (\(c :: Char) -> "char: " ++ show c)
     @> (\(i :: Int) -> "int: " ++ show i)
     @> (\(l :: [()]) -> "list length: " ++ show (length l))
     @> (\(s :: String) -> "string: " ++ s)
     @> typesExhausted
 main :: IO ()
 main = do
     putStrLn $ showMyUnion $ liftUnion (4 :: Int)
     putStrLn $ showMyUnion $ liftUnion 'a'
     putStrLn $ showMyUnion $ liftUnion [(), ()]

which prints:

 int: 4
 char: 'a'
 list length: 2

Casting to an unrelated type does not cause errors; In the above example,showMyUnion contains a String case despite MyUnion not containing String - superfluous cases are ignored, for the time being.

typesExhausted is NOT a catchall. It is a null case, and using it as a catchall (or forgetting to provide a certain case, for instance) will result in an error like:

 example.hs:12:8:
     Couldn't match type ‘Int : ('[] :\ [Char])’ with ‘'[]’
     Expected type: Union ('[Int] :\ String) -> String
       Actual type: Union '[] -> String
     In the second argument of ‘(@>)’, namely ‘typesExhausted’
     In the second argument of ‘(@>)’, namely
       ‘(\ (s :: String) -> "string: " ++ s) @> typesExhausted’

The left-hand parts of the ': (think type-level `(:)`) are the cases that still need to be satisfied.

Trying to lift an incorrect type to a Union will cause an error resembling:

 example.hs:20:30:
     No instance for (Data.OpenUnion.Internal.LiftToUnion '[] [Char])
       arising from a use of ‘liftUnion’
     In the second argument of ‘($)’, namely ‘liftUnion "asdf"’
     In the second argument of ‘($)’, namely
       ‘showMyUnion $ liftUnion "asdf"’
     In a stmt of a 'do' block:
       putStrLn $ showMyUnion $ liftUnion "asdf"

The original use case for this library was code like this (snipped from some record/playback logic):

 type TrackStates = '[Stopped, Recording, Playing]

 startRecording
   :: Union (TrackStates :\ Recording)
   -> ([Note], Union '[Recording])

The `(:\)` type-level operator is for removal from a set, i.e. startRecording can be applied to a track in any state except the Recording state.


Properties

Versions0.1.0, 0.1.0.0, 0.1.0.1 (info)
Dependenciesbase (==4.*), open-union
LicenseMIT
AuthorBen Foppa
Maintainerbenjamin.foppa@gmail.com
CategoryData
Home pagehttps://github.com/RobotGymnast/open-union
Source repositoryhead: git clone https://github.com/RobotGymnast/open-union.git
Executablesexample
Upload dateMon Jun 30 15:44:05 UTC 2014
Uploaded byBenFoppa
Downloads158 total (28 in last 30 days)

Modules

[Index]

Downloads

Maintainers' corner

For package maintainers and hackage trustees