open-union: Extensible, type-safe unions.
This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.
Warnings:
- A 'license-file' is not specified.
- 'ghc-options: -O2' is rarely needed. Check that it is giving a real benefit and not just imposing longer compile times on your users.
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
Versions | 0.1.0, 0.1.0.0, 0.1.0.0, 0.1.0.1, 0.2.0.0, 0.3.0.0, 0.4.0.0 |
---|---|
Change log | None available |
Dependencies | base (>=4 && <5), open-union [details] |
License | MIT |
Author | Ben Foppa |
Maintainer | benjamin.foppa@gmail.com |
Category | Data |
Home page | https://github.com/RobotGymnast/open-union |
Source repo | head: git clone https://github.com/RobotGymnast/open-union.git |
Uploaded | by BenFoppa at 2014-06-30T15:32:31Z |
Modules
- Data
- Data.OpenUnion
- Data.OpenUnion.Internal
- Data.OpenUnion
Downloads
- open-union-0.1.0.0.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)
Maintainer's Corner
Package maintainers
For package maintainers and hackage trustees