当前位置: 首页 > 知识库问答 >
问题:

类型族不能返回RankN类型-变通方法还是替代方法?

云长恨
2023-03-14
type family LensOrTraversal key keys s t a b where
    LensOrTraversal key '[] s t a b = 
        Traversal s t a b
    LensOrTraversal key (key =: val ': xs) s t a b = 
        Lens s t a b
    LensOrTraversal key (foo =: bar ': xs) s t a b = 
        LensOrTraversal key xs s t a b
/home/matt/Projects/hash-rekt/src/Data/HashRecord/Internal.hs:433:5: 
error:
    • Illegal polymorphic type: Traversal s t a b
    • In the equations for closed type family ‘LensOrTraversal’
      In the type family declaration for ‘LensOrTraversal’
>>> let testMap = empty & field @"foo" .~ 'a'
>>> :t testMap
HashRecord '["foo" =: Char]
>>> testMap ^. field @"foo" 
'a'
>>> testMap ^. field @"bar"
Type error
>>> testMap ^? field @"bar"
Nothing

它遵循常用的lens习惯用法。我可以提供一个fieldtraversal函数来执行我想要的操作,但是如果可能的话,我更希望重载field这个名称。您将如何克服类型族的这种限制?

共有1个答案

公孙俭
2023-03-14

一个透镜已经是一个遍历,只是它的Rank2量词没有使用完整的约束(它只需要functor,而不需要applicative)。

type Lens s t a b      = ∀ f . Functor f     => (a -> f b) -> s -> f t
type Traversal s t a b = ∀ f . Applicative f => (a -> f b) -> s -> f t

正是在这个约束的级别上,您应该引入您的类型族:

import GHC.Exts (Constraint)
type family FieldOpticConstraint key keys :: (* -> *) -> Constraint where
  FieldOpticConstraint key '[] = Applicative
  FieldOpticConstraint key (key =: val ': xs) = Functor
  FieldOpticConstraint key (_ ': xs) = FieldOpticConstraint key xs

field不应生成lensortraversal,而应始终生成具有由类型族确定的约束的自定义Rank2-signature。

 类似资料:
  • 问题内容: 这就是我想要做的。使用反射,我想获取所有方法及其返回类型(非泛型)。我一直在这样做。但是,当我遇到返回类型未知的方法时,我遇到了限制。 我如何知道方法的返回类型是否通用?我没有奢求在运行时拥有对象。我正在尝试使用Google 或使用抽象类来获取类型信息。我想关联到对象的方法。 有人认为Java不保留通用信息。在这种情况下,为什么第一次强制转换有效而第二次强制转换无效。 任何帮助表示赞赏

  • 问题内容: 考虑以下示例(OOP书籍中的典型示例): 我有一Animal堂课,每个人Animal可以有很多朋友。 和子类喜欢Dog,Duck,Mouse等里面加如特定行为bark(),quack()等等。 这是Animal课程: 这是一些带有大量类型转换的代码片段: 有什么办法可以将泛型用于返回类型来摆脱类型转换,所以我可以说 这是一些带有返回类型的初始代码,这些代码作为从未使用过的参数传递给该方

  • 我正在Java开发一个纸牌游戏,我试图比较hashMap中的键和ArrayList中的元素(两者都是对象)。hashCode()和equals()被重写,但出现了一个错误,我不确定它的哪一部分是错误的。 这是纸牌课 我们要做的比较 错误:点击查看错误图片

  • 我正在努力学习Spring Boot微服务。现在,如果我的任何呼叫服务关闭,我将尝试使用resilience4j实现断路器。 如果我将回退方法返回类型设置为实际的方法返回类型,那么它可以正常工作,但是我不能显示我的服务关闭的信息。因为它随后在对象的字段中发送响应null。但是如果我在实际方法上将返回类型更改为String,并且在回退中,那么我将无法以JSON的形式获取对象值。 是否有可能返回字符串

  • 问题内容: 背景 我曾经写过这种方法: 应该这样称呼它: 这很好用(尽管我在研究当前容易出错的问题时在这里的答案中已经看到)。 目前的情况 无论如何,现在我正在编写以下代码(在扩展javax.servlet.jsp.tagext.TagSupport的类中): 目的是可以这样称呼: 我的评估方法中的代码显然不起作用。的第二个参数应该是Class对象。这导致我: 我的问题 如何获得通用(返回)类型的

  • Java中是否有一种方法可以通过一个方法的声明返回不同的类型? 我希望此方法返回一个对象,并在函数调用时将其转换为正确的类型。这就是我的想法,但它不是这样工作的。我是否需要某种通用返回类型来执行此操作?解决这个问题的最佳方法是什么?