标签: implicit-parameters

如何用“反射”包替换 ImplicitParams?

我有一个枚举类型,例如

data MyType = A | B
Run Code Online (Sandbox Code Playgroud)

我希望能够将这种类型的值隐式传递给我的函数。我可以使用ImplicitParamsGHC 扩展来做到这一点:

type HasMyType = (?myType :: MyType)

myFun :: HasMyType => String
myFun = case ?myType of
    A -> "Foo"
    B -> "Bar"
Run Code Online (Sandbox Code Playgroud)

但是我多次听说,最好使用 Haskell 包反射来完成这项任务。不幸的是,reflection文档没有解释如何使用库编写类似的代码。弄清楚它并不是那么简单。

所以,我的问题是,是否可以使用该reflection库来实现类似的代码并满足以下要求?

  1. 的值MyType应该隐式传递。
  2. 如果HasMyType未指定约束,MyType则应采用默认值。
  3. 应该可以HasMyType在一个地方覆盖通过约束传递的值,例如在应用程序的开头。

这样的事情可能吗?或者使用reflection库最接近的近似值是什么?

reflection haskell typeclass implicit-parameters

8
推荐指数
1
解决办法
137
查看次数

模板Haskell和隐式参数

有没有办法用隐式参数创建函数或使用模板haskell让绑定与隐式参数?

即使用模板haskell生成这样的签名是可能的:

 doSomething :: (?context :: Context) => m a
Run Code Online (Sandbox Code Playgroud)

或者像这样的调用:

 invoc = let ?context = newContext in doSomething
Run Code Online (Sandbox Code Playgroud)

我找不到合适的代数数据类型,也没有任何函数可以帮助我在模板haskellAPI文档中讨论这个主题.我正在使用GHC 7.4.2.

如果模板haskell中没有对此扩展的本机支持,是否还有其他可能在编译期间注入代码(可能类似于模板haskell中的一般"代码注入函数"?).

编辑:我尝试了评论中的建议,这是发生的事情:

runQ [d| f :: (?c :: String) => Int ; f = 7 |]

<interactive>:10:17: parse error on input `c'
Run Code Online (Sandbox Code Playgroud)

这有效:

 runQ [d| f :: Int ; f = 7|]
 [SigD f_0 (ConT GHC.Types.Int),ValD (VarP f_0) (NormalB (LitE (IntegerL 7))) []]
Run Code Online (Sandbox Code Playgroud)

似乎没有得到支持.

haskell template-haskell implicit-parameters

6
推荐指数
1
解决办法
285
查看次数

隐式参数是GHC中内联的难点吗?

我很好奇Kiselyov和Shan 在" 功能性珍珠:隐式配置"一文中讨论的对隐式参数的反对意见.

在存在隐式参数的情况下内联代码(β-reduce)是不可靠的.

真?我希望GHC应该内联到与传递的隐式参数相同的范围,不是吗?

我相信我理解他们的反对意见:

如果添加,删除或更改其签名,则术语的行为可能会发生变化.

GHC的用户文档解释说,程序员必须注意多态递归单态限制.这是不是因为内联问题意味着什么?

我假设这个多态递归示例还涵盖了"概括隐含参数"的意思吗?还要别的吗?

Data.ReflectionReifiesStorable类型类是否真的是解决这些困难的合理解决方案?它似乎每次访问时都会对整个隐式数据结构进行反序列化,这听起来对性能来说是灾难性的.例如,我们可能希望我们的隐含信息是Cayley表或占用ram gig的字符表,并且必须在数百万代数运算期间访问.

是否有一些更好的解决方案采用隐式参数,或者编译器可以在幕后轻松优化的另一种技术,同时仍然通过类型系统使用状态线程或其他保证更多?

haskell lambda-calculus ghc implicit-parameters

5
推荐指数
1
解决办法
520
查看次数

如何在Scala中使用隐式参数扩展类

B类(隐式imp:Int)扩展AC {}

对象C扩展B {

}

错误:无法找到参数imp的隐含值

这就是我要寻找的:如何在类级别为隐式参数提供默认值

scala implicit-parameters

3
推荐指数
1
解决办法
1295
查看次数

隐式值的隐式转换是否可以满足隐式参数?

我正在定义一些Scala implicits,以便更轻松地使用特定的不可更改的Java类集.下面的Scala代码是一个简单的例子,显然看起来很疯狂,在现实世界中,我试图从Monkey,Tree&Duck中隐含地获取特定资源(而不是数字时代),以便在各种方法中使用purchaseCandles():

// actually 3 Java classes I can not change:
case class Monkey(bananas: Int) 
case class Tree(rings: Int)
case class Duck(quacks: Seq[String])

// implicits I created to make my life easier...
implicit def monkey2Age(monkey: Monkey): Int = monkey.bananas / 1000
implicit def tree2Age(tree: Tree): Int = tree.rings
implicit def duck2Age(duck: Duck): Int = duck.quacks.size / 100000

// one of several helper methods that I would like to define only once,
// only useful if they can use …
Run Code Online (Sandbox Code Playgroud)

scala implicit-conversion implicit-parameters

1
推荐指数
1
解决办法
272
查看次数