Safe Haskell | None |
---|---|
Language | Haskell2010 |
converting between partial functions and maps.
(for doctest)
>>>
:set +m
>>>
:set -XLambdaCase
>>>
:{
let uppercasePartial :: (MonadThrow m) => Char -> m Char -- :: Partial Char Char uppercasePartial = \case 'a' -> return 'A' 'b' -> return 'B' 'z' -> return 'Z' _ -> failed "uppercasePartial" :}
a (safely-)partial function is isomorphic with a Map
:
fromFunctionM
.toFunctionM
=id
toFunctionM
.fromFunctionM
=id
modulo the error thrown.
- toFunction :: (Enumerable a, Ord a) => Map a b -> Maybe (a -> b)
- toFunctionM :: (Enumerable a, Ord a) => Map a b -> Partial a b
- unsafeToFunction :: Ord a => Map a b -> a -> b
- isTotalM :: (Enumerable a, Ord a) => Partial a b -> Maybe (a -> b)
- unsafeFromList :: Ord a => [(a, b)] -> a -> b
- functionEnumerated :: (Enumerable a, Enumerable b, Ord a, Ord b) => [a -> b]
- functionCardinality :: forall a b proxy. (Enumerable a, Enumerable b) => proxy (a -> b) -> Natural
- extensionallyEqual :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool
- extensionallyUnequal :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool
- functionShowsPrec :: (Enumerable a, Show a, Show b) => Int -> (a -> b) -> ShowS
- displayFunction :: (Enumerable a, Show a, Show b) => (a -> b) -> String
- displayInjective :: (Enumerable a, Ord a, Ord b, Show a, Show b) => (a -> b) -> Maybe String
- mappingEnumeratedAt :: [a] -> [b] -> [[(a, b)]]
- crossProduct :: [a] -> [b] -> [[(a, b)]]
Documentation
toFunction :: (Enumerable a, Ord a) => Map a b -> Maybe (a -> b) Source
convert a map to a function, if the map is total.
>>>
let (Just not_) = toFunction (Map.fromList [(False,True),(True,False)])
>>>
not_ False
True
toFunctionM :: (Enumerable a, Ord a) => Map a b -> Partial a b Source
convert a (safely-)partial function to a map.
lookup failures are throwM
n as a PatternMatchFail
.
>>>
let idPartial = toFunctionM (Map.fromList [(True,True)])
>>>
idPartial True
True
>>>
idPartial False
*** Exception: toFunctionM
unsafeToFunction :: Ord a => Map a b -> a -> b Source
wraps lookup
isTotalM :: (Enumerable a, Ord a) => Partial a b -> Maybe (a -> b) Source
refines the partial function, if total.
>>>
:{
let myNotM :: Monad m => Bool -> m Bool myNotM False = return True myNotM True = return False :}>>>
let (Just myNot) = isTotalM myNotM
>>>
myNot False
True
unsafeFromList :: Ord a => [(a, b)] -> a -> b Source
wraps lookup
>>>
(unsafeFromList [(False,True),(True,False)]) False
True>>>
(unsafeFromList [(False,True),(True,False)]) True
False
functionEnumerated :: (Enumerable a, Enumerable b, Ord a, Ord b) => [a -> b] Source
functionCardinality :: forall a b proxy. (Enumerable a, Enumerable b) => proxy (a -> b) -> Natural Source
|b| ^ |a|
extensionallyEqual :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool Source
are all pairs of outputs the same for the same input? (short-ciruits).
extensionallyUnequal :: (Enumerable a, Eq b) => (a -> b) -> (a -> b) -> Bool Source
is any pair of outputs different for the same input? (short-ciruits).
functionShowsPrec :: (Enumerable a, Show a, Show b) => Int -> (a -> b) -> ShowS Source
show all inputs and their outputs, as unsafeFromList [...]
.
displayFunction :: (Enumerable a, Show a, Show b) => (a -> b) -> String Source
show all inputs and their outputs, as case ...
.
displayInjective :: (Enumerable a, Ord a, Ord b, Show a, Show b) => (a -> b) -> Maybe String Source
mappingEnumeratedAt :: [a] -> [b] -> [[(a, b)]] Source
[(a,b)]
is a mapping, [[(a,b)]]
is a list of mappings.
>>>
let orderingPredicates = mappingEnumeratedAt [LT,EQ,GT] [False,True]
>>>
print $ length orderingPredicates
8>>>
printMappings $ orderingPredicates
(LT,False) (EQ,False) (GT,False) (LT,False) (EQ,False) (GT,True) (LT,False) (EQ,True) (GT,False) (LT,False) (EQ,True) (GT,True) (LT,True) (EQ,False) (GT,False) (LT,True) (EQ,False) (GT,True) (LT,True) (EQ,True) (GT,False) (LT,True) (EQ,True) (GT,True)
where the (total) mapping:
(LT,False) (EQ,False) (GT,True)
is equivalent to the function:
\case LT -> False EQ -> False GT -> True
crossProduct :: [a] -> [b] -> [[(a, b)]] Source
>>>
let crossOrderingBoolean = crossProduct [LT,EQ,GT] [False,True]
>>>
printMappings $ crossOrderingBoolean
(LT,False) (LT,True) (EQ,False) (EQ,True) (GT,False) (GT,True)
the length of the outer list is the size of the first set, and the length of the inner list is the size of the second set.
>>>
print $ length crossOrderingBoolean
3>>>
print $ length (head crossOrderingBoolean)
2