{-# LANGUAGE GADTs #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
import GHC.Exts (Constraint)
class Function f where
type Constraints f a :: Constraint
type instance Constraints f a = ()
type Result f a
type instance Result f a = a
applyFunc :: (Constraints f a) => f -> a -> Result f a
pairmap :: (Function f, Constraints f a, Constraints f b) => f -> (a, b) -> (Result f a, Result f b)
pairmap f (x,y) = (applyFunc f x, applyFunc f y)
data NumFunc where
NumFunc
:: (forall a
. Num a
=> a
-> a
) -> NumFunc
instance Function NumFunc where
type Constraints NumFunc a
= (Num a
) applyFunc (NumFunc f) = f
data EnumFunc where
EnumFunc
:: (forall a
. Enum a
=> a
-> a
) -> EnumFunc
instance Function EnumFunc where
type Constraints EnumFunc a
= (Enum a
) applyFunc (EnumFunc f) = f
data MaybeFunc where
MaybeFunc
:: (forall a
. a
-> Maybe a
) -> MaybeFunc
instance Function MaybeFunc where
type Result MaybeFunc a
= Maybe a
applyFunc (MaybeFunc f) = f
y1
= pairmap
(NumFunc
(+2)) (1::Int, 2::Float)y2
= pairmap
(EnumFunc
succ) (1::Int, 'a')y3 = pairmap (MaybeFunc Just) ('a', True)
main = do
ey0jIExBTkdVQUdFIEdBRFRzICMtfQp7LSMgTEFOR1VBR0UgRGF0YUtpbmRzICMtfQp7LSMgTEFOR1VBR0UgS2luZFNpZ25hdHVyZXMgIy19CnstIyBMQU5HVUFHRSBUeXBlRmFtaWxpZXMgIy19CnstIyBMQU5HVUFHRSBSYW5rTlR5cGVzICMtfQoKaW1wb3J0IEdIQy5FeHRzIChDb25zdHJhaW50KQoKY2xhc3MgRnVuY3Rpb24gZiB3aGVyZQogIHR5cGUgQ29uc3RyYWludHMgZiBhIDo6IENvbnN0cmFpbnQKICB0eXBlIGluc3RhbmNlIENvbnN0cmFpbnRzIGYgYSA9ICgpCiAgdHlwZSBSZXN1bHQgZiBhCiAgdHlwZSBpbnN0YW5jZSBSZXN1bHQgZiBhID0gYQogIGFwcGx5RnVuYyA6OiAoQ29uc3RyYWludHMgZiBhKSA9PiBmIC0+IGEgLT4gUmVzdWx0IGYgYQoKcGFpcm1hcCA6OiAoRnVuY3Rpb24gZiwgQ29uc3RyYWludHMgZiBhLCBDb25zdHJhaW50cyBmIGIpID0+IGYgLT4gKGEsIGIpIC0+IChSZXN1bHQgZiBhLCBSZXN1bHQgZiBiKQpwYWlybWFwIGYgKHgseSkgPSAoYXBwbHlGdW5jIGYgeCwgYXBwbHlGdW5jIGYgeSkKCmRhdGEgTnVtRnVuYyB3aGVyZQogIE51bUZ1bmMgOjogKGZvcmFsbCBhLiBOdW0gYSA9PiBhIC0+IGEpIC0+IE51bUZ1bmMKCmluc3RhbmNlIEZ1bmN0aW9uIE51bUZ1bmMgd2hlcmUKICB0eXBlIENvbnN0cmFpbnRzIE51bUZ1bmMgYSA9IChOdW0gYSkKICBhcHBseUZ1bmMgKE51bUZ1bmMgZikgPSBmCgpkYXRhIEVudW1GdW5jIHdoZXJlCiAgRW51bUZ1bmMgOjogKGZvcmFsbCBhLiBFbnVtIGEgPT4gYSAtPiBhKSAtPiBFbnVtRnVuYwoKaW5zdGFuY2UgRnVuY3Rpb24gRW51bUZ1bmMgd2hlcmUKICB0eXBlIENvbnN0cmFpbnRzIEVudW1GdW5jIGEgPSAoRW51bSBhKQogIGFwcGx5RnVuYyAoRW51bUZ1bmMgZikgPSBmCgpkYXRhIE1heWJlRnVuYyB3aGVyZQogIE1heWJlRnVuYyA6OiAoZm9yYWxsIGEuIGEgLT4gTWF5YmUgYSkgLT4gTWF5YmVGdW5jCgppbnN0YW5jZSBGdW5jdGlvbiBNYXliZUZ1bmMgd2hlcmUKICB0eXBlIFJlc3VsdCBNYXliZUZ1bmMgYSA9IE1heWJlIGEKICBhcHBseUZ1bmMgKE1heWJlRnVuYyBmKSA9IGYKCnkxID0gcGFpcm1hcCAoTnVtRnVuYyAoKzIpKSAoMTo6SW50LCAyOjpGbG9hdCkKeTIgPSBwYWlybWFwIChFbnVtRnVuYyBzdWNjKSAoMTo6SW50LCAnYScpCnkzID0gcGFpcm1hcCAoTWF5YmVGdW5jIEp1c3QpICgnYScsIFRydWUpCgptYWluID0gZG8KICBwcmludCB5MQogIHByaW50IHkyCiAgcHJpbnQgeTMK