使用Typeable在运行时部分应用功能(任何时间类型匹配)

| 通用编程时间! 如果我有一个功能:
f :: a1 -> a2 -> a3 -> ... -> an
和一个值
v :: aX   -- where 1 <= x < n
在编译时不知道
f
的哪个自变量的值
v
是(如果有)正确的类型,是否可以将
f
部分应用于
v
? (使用Typeable,Data,TH或其他任何技巧) 更可靠一点,我可以在运行时构造函数
g
(如下)吗?实际上,它不一定是多态的,我所有的类型都是单态的!
g :: (a1 -> a2 -> a3 -> a4 -> a5) -> a3 -> (a1 -> a2 -> a4 -> a5)
g f v = \\x y z -> f x y v z
我知道,使用Typeable(特别是
typeRepArgs
),
v
f
的第三个参数,但这并不意味着我有办法部分应用
f
。 我的代码可能看起来像:
import Data.Typeable

data Box = forall a. Box (TyRep, a)

mkBox :: Typeable a => a -> Box
mkBox = (typeOf a, a)

g :: Box -> Box -> [Box]
g (Box (ft,f)) (Box (vt,v)) = 
    let argNums = [n | n <- [1..nrArgs], isNthArg n vt ft]
    in map (mkBox . magicApplyFunction f v) argNums

isNthArg :: Int -> TyRep -> TyRep -> Bool
isNthArg n arg func = Just arg == lookup n (zip [1..] (typeRepArgs func))

nrArgs :: TyRep -> Int
nrArgs = (\\x -> x - 1) . length . typeRepArgs
有什么东西可以实现“ 13”吗? 编辑:我终于回到玩这个。神奇的应用功能是:
buildFunc :: f -> x -> Int -> g
buildFunc f x 0 = unsafeCoerce f x
buildFunc f x i =
        let !res = \\y -> (buildFunc (unsafeCoerce f y) x (i-1))
        in unsafeCoerce res
    
已邀请:
我暂时不打算在此处编写整个解决方案,但是我敢肯定,可以仅使用
Data.Dynamic
Typeable
完成此操作。 ѭ17和ѭ18的来源应提供关键要素:
dynApply :: Dynamic -> Dynamic -> Maybe Dynamic
dynApply (Dynamic t1 f) (Dynamic t2 x) =
  case funResultTy t1 t2 of
    Just t3 -> Just (Dynamic t3 ((unsafeCoerce f) x))
    Nothing -> Nothing


funResultTy :: TypeRep -> TypeRep -> Maybe TypeRep
funResultTy trFun trArg
  = case splitTyConApp trFun of
      (tc, [t1,t2]) | tc == funTc && t1 == trArg -> Just t2
      _ -> Nothing
为了简单起见,我要20英镑。后者以参数的类型表示形式列表开始。
magicApply
将在框中寻找第一个匹配的TypeRep,并替换值的
Dynamic
。然后,您可能会得到一个ѭ23,给定一个ѭ24which,所有参数已被魔术应用,实际上执行
dynApply
调用以产生结果动态结果。     
嗯..只能输入?好的旧的OverlappingInstances怎么样?
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies,
UndecidableInstances, IncoherentInstances, ScopedTypeVariables #-}

class Magical a b c where
    apply :: a -> b -> c

instance (AreEqual a c e, Magical\' e (a -> b) c r) => Magical (a -> b) c r where
    apply f a = apply\' (undefined :: e) f a


class Magical\' e a b c where
    apply\' :: e -> a -> b -> c

instance (r ~ b) => Magical\' True (a -> b) a r where
    apply\' _ f a = f a

instance (Magical b c d, r ~ (a -> d)) => Magical\' False (a -> b) c r where
    apply\' _ f c = \\a -> apply (f a) c


data True
data False

class AreEqual a b r
instance (r ~ True) => AreEqual a a r
instance (r ~ False) => AreEqual a b r


test :: Int -> Char -> Bool
test i c = True

t1 = apply test (5::Int)
t2 = apply test \'c\'
    

要回复问题请先登录注册