gpt4 book ai didi

haskell - 函数作为要在模板 haskell 引用中使用的参数

转载 作者:行者123 更新时间:2023-12-04 20:06:24 25 4
gpt4 key购买 nike

这是对 Lift instance for a function? 的部分跟进.然而,答案是要么全局定义函数,要么在引用中重写它。但是,我们将使用 foo很多具有不同功能的 f来自 let 的范围内.这使得我们几乎不可能定义 f 的多个全局版本。后一种解决方案,在引用中编写我们的函数,似乎相当于在函数上编写一个电梯。

那么,有没有什么方法可以提升函数作为参数在模板 Haskell 引用中使用?

A 非常人为的例子:

foo.hs

{-# Language TemplateHaskell #-}
import Language.Haskell.TH

foo :: (Int->Int) -> Int -> ExpQ
foo f x = [|f x|]

g :: ExpQ
g =
let
f = (\x -> x+1)
f' = (\x' -> f(x') + 1)
in foo f' 0

将失败:
foo.hs:5:11:
No instance for (Language.Haskell.TH.Syntax.Lift (Int -> Int))
arising from a use of ‘Language.Haskell.TH.Syntax.lift’
In the expression: Language.Haskell.TH.Syntax.lift f
In the expression:
[| f x |]
pending(rn) [x, f]
In an equation for ‘foo’:
foo f x
= [| f x |]
pending(rn) [x, f]

最佳答案

无法使用提升功能。然而,有两种可能的替代方案可能适合您:

只提升函数的结果,在编译时应用函数

在您的特殊情况下,因为您在编译时知道 xf ,你可以计算 f x在编译时,只拼接结果:

foo :: (Int->Int) -> Int -> ExpQ
foo f x = [| $(lift $ f x) |]
-- = lift $ f x
-- foo f = lift . f

这不会改变 f 的类型签名,但它要求您知道要提供给 f 的所有参数。 .您需要导入 Language.Haskell.TH.Syntaxlift功能。

将函数的表达式作为参数传递

如果您不能使用第一种解决方案,还有另一种选择。您现在不是传递函数,而是传递一个函数的拼接作为参数:
foo :: ExpQ -> Int -> ExpQ
foo f x = [| $f x |]

有两个缺点:首先,你失去了类型安全性,因为它没有检查拼接是否真的扩展到可以应用于 Int 的东西。 .您需要更改您的调用代码,如下所示:
g :: ExpQ
g =
let
f = [| \x -> x+1 |]
f' = [| \x' -> $f x' + 1 |]
in foo f' 0

关于haskell - 函数作为要在模板 haskell 引用中使用的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25618803/

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