Copyright | (c) Anselm Jonas Scholl 2016 |
---|---|
License | BSD3 |
Maintainer | anselm.scholl@tu-harburg.de |
Stability | experimental |
Portability | non-portable (uses type families and more) |
Safe Haskell | None |
Language | Haskell2010 |
This module provides the reverseArgs
function which flips the arguments
of a function of arbitrary arity. The return value of the flipped function
can not be fully polymorphic as this could imply it is a function.
Example:
myFlip :: (a -> b -> c -> d -> [e]) -> d -> c -> b -> a -> [e] myFlip = reverseArgs
However, if you supply a proof (of the form IsFun a ~ 'False
) that a is not
a function, you can also return a polymorphic type.
Example:
myFlip :: IsFun e ~ 'False => (a -> b -> c -> d -> e) -> d -> c -> b -> a -> e myFlip = reverseArgs
- reverseArgs :: (ReverseArgs (BoxResult a), Coercible a (BoxResult a), Coercible (ReversedArgs a) (BoxResult (ReversedArgs a)), ReversedArgs (BoxResult a) ~ BoxResult (ReversedArgs a)) => a -> ReversedArgs a
- type family IsFun f
- type family ApplyLast a z
- type family MatchLastArg a b z
- class ApplyingLast f z | f -> z where
- type ReversedArgs a = If (IsFun a) (ReverseOneArg a) a
- type family ReverseOneArg a
- type InsertAtEnd a f = If (IsFun f) (InsertAtEndStep a f) (a -> f)
- type family InsertAtEndStep a f
- class ReverseArgs a where
- reverseArgs' :: a -> ReversedArgs a
- type BoxResult a = If (IsFun a) (BoxArrow a) (Identity a)
- type family BoxArrow a
- boxResult :: Coercible a (BoxResult a) => a -> BoxResult a
- unboxResult :: Coercible a (BoxResult a) => BoxResult a -> a
Reversing arguments
reverseArgs :: (ReverseArgs (BoxResult a), Coercible a (BoxResult a), Coercible (ReversedArgs a) (BoxResult (ReversedArgs a)), ReversedArgs (BoxResult a) ~ BoxResult (ReversedArgs a)) => a -> ReversedArgs a Source
Reverse the arguments of a function. Does work with polymorphic return values if you supply a proof that the result is not a function.
Utilities
Determine whether the argument is a function.
Internal types and functions
Applying the last argument
type family ApplyLast a z Source
Apply the last argument of a function to it.
ApplyLast (a -> b) z = If (IsFun b) (a -> ApplyLast b z) (MatchLastArg a b z) |
class ApplyingLast f z | f -> z where Source
Like ApplyLast
, but on the value level.
((~) * (ApplyLast (a -> b -> c) z) (a -> ApplyLast (b -> c) z), ApplyingLast (b -> c) z) => ApplyingLast (a -> b -> c) z Source | |
((~) Bool (IsFun b) False, (~) * a c) => ApplyingLast (a -> b) c Source |
Reversing arguments
type ReversedArgs a = If (IsFun a) (ReverseOneArg a) a Source
Reverse the arguments of a function.
type family ReverseOneArg a Source
Reverse one of the arguments of a function and recurse for the rest.
ReverseOneArg (a -> b) = InsertAtEnd a (ReversedArgs b) |
type InsertAtEnd a f = If (IsFun f) (InsertAtEndStep a f) (a -> f) Source
Insert an argument at the end.
type family InsertAtEndStep a f Source
Shift one to the left and insert something at the end.
InsertAtEndStep a (x -> y) = x -> InsertAtEnd a y |
class ReverseArgs a where Source
reverseArgs' :: a -> ReversedArgs a Source
Reverse the arguments of some function. Does not work with functions
with fully polymorphic return values, use reverseArgs
instead.
(~) * (ReversedArgs a) a => ReverseArgs a Source | |
(ApplyingLast (a -> b) z, (~) * (ReversedArgs (a -> b)) (z -> r), (~) * (ReversedArgs (ApplyLast (a -> b) z)) r, ReverseArgs (ApplyLast (a -> b) z)) => ReverseArgs (a -> b) Source |
Boxing results
type BoxResult a = If (IsFun a) (BoxArrow a) (Identity a) Source
Box the result in the Identity
monad.
Box the result of a function in the Identity
monad.