name: open-union version: 0.1.0.0 synopsis: Extensible, type-safe unions. category: Data license: MIT author: Ben Foppa homepage: https://github.com/RobotGymnast/open-union maintainer: benjamin.foppa@gmail.com build-type: Simple cabal-version: >= 1.9.2 description: Extensible, type-safe unions. This package is very new and likely to change. . Basic usage example (language tags ommitted due to ) . > 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. library hs-source-dirs: . ghc-options: -Wall exposed-modules: Data.OpenUnion Data.OpenUnion.Internal build-depends : base == 4.* executable example hs-source-dirs: . main-is: example.hs ghc-options: -Wall -fllvm -O2 build-depends : base == 4.* , open-union source-repository head type: git location: https://github.com/RobotGymnast/open-union.git