Использование 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

Есть ли что-нибудь, что может реализовать magicApplyFunction ?

РЕДАКТИРОВАТЬ: Я наконец вернулся к игре с этим. Волшебная функция apply:

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
6
задан Thomas M. DuBuisson 27 April 2011 в 17:24
поделиться