gpt4 book ai didi

haskell - 使用 Typeable 在运行时部分应用函数(任何类型匹配的时间)

转载 作者:行者123 更新时间:2023-12-02 18:35:20 25 4
gpt4 key购买 nike

通用编程时间!

如果我有一个函数:

f :: a1 -> a2 -> a3 -> ... -> an

和一个值

v :: aX   -- where 1 <= x < n

在编译时不知道 f 的哪个参数中值 v 是正确的类型(如果有),我可以部分应用 fv? (使用 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),vf 的第三个参数,但这并不意味着我有办法部分应用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吗?

编辑:我终于又开始玩这个了。神奇的应用函数是:

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.DynamicTypeable 来完成。 dynApplyfunResultTy 的源代码应提供关键元素:

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

为了简单起见,我会输入 Box = (Dynamic, [Either TypeRep Dynamic])。后者从参数的类型代表列表开始。 magicApply 将在框中查找第一个匹配的 TypeRep 并替换该值的Dynamic。然后,您可以有一个 extract,它给定一个所有参数都已被 magicapplied 的 Box,实际上执行 dynApply 调用以生成动态结果.

关于haskell - 使用 Typeable 在运行时部分应用函数(任何类型匹配的时间),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5745302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com