open-union 0.1.0 → 0.1.0.0
raw patch · 2 files changed
+77/−69 lines, 2 files
Files
- LICENSE +8/−0
- open-union.cabal +69/−69
+ LICENSE view
@@ -0,0 +1,8 @@+Copyright (C) 2014 Ben Foppa+++Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
open-union.cabal view
@@ -1,82 +1,82 @@ name: open-union-version: 0.1.0+version: 0.1.0.0 synopsis: Extensible, type-safe unions. category: Data license: MIT+license-file: LICENSE 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 TypeOperators #-}- > {-# LANGUAGE ScopedTypeVariables #-}- > 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.+ 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. library hs-source-dirs: .