Thời gian lập trình chung!Sử dụng Typeable để áp dụng một phần chức năng tại thời gian chạy (bất kỳ loại thời gian nào phù hợp)
Nếu tôi có một chức năng:
f :: a1 -> a2 -> a3 -> ... -> an
và một giá trị
v :: aX -- where 1 <= x < n
Mà không biết tại thời gian biên dịch mà trong những lập luận của f
giá trị v
là loại phù hợp với (nếu có) , tôi có thể áp dụng một phần f
cho v
không? (sử dụng Typeable, Data, TH hoặc bất kỳ mẹo nào khác)
Hơi chắc chắn hơn, tôi có thể xây dựng hàm g
(bên dưới) tại thời gian chạy không? Nó không thực sự phải là đa hình, tất cả các loại của tôi sẽ là đơn hình!
g :: (a1 -> a2 -> a3 -> a4 -> a5) -> a3 -> (a1 -> a2 -> a4 -> a5)
g f v = \x y z -> f x y v z
Tôi biết rằng, sử dụng Typeable (typeRepArgs
cụ thể), v
là đối số thứ 3 của f
, nhưng điều đó không có nghĩa là tôi có một cách để một phần áp dụng f
.
Mã của tôi có lẽ sẽ giống như sau:
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
Có điều gì mà có thể thực hiện magicApplyFunction
?
EDIT: Cuối cùng tôi đã trở lại để chơi với điều này. Chức năng ma thuật áp dụng là:
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
Không có gì sai với ** g **, theo như tôi thấy, và tính đa hình cũng không quan trọng. Cũng như bạn có thể sử dụng lật mọi lúc bạn có một hàm và đối số thứ 2, bạn biết đấy. – Ingo
Nhưng tôi không có thời gian biên dịch! Làm thế nào tôi có thể tạo ra nó trong thời gian chạy? IIRC, tôi không thể chuyển các chức năng qua lại từ/gợi ý –
Viết hàm để áp dụng nó thông qua thứ không phải là vấn đề - vấn đề là loại giá trị bạn nhận được (Dynamic/Box) là, bạn nhận ra, lựa chọn duy nhất của bạn. – sclv