- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我尝试使用 generic-lens 包中的 @ 符号访问某个类型的字段,GHC 会提示启用 DataKinds 扩展。你能用简单的英语向我解释一下 generic-lens 和 DataKinds 的关系吗?
谢谢
最佳答案
DataKinds
是一个允许将数据类型提升到类型级别的扩展。这恰恰意味着一堆蠕虫(这是依赖类型的一步),所以我会尝试将这个解释集中在通用镜头使用它的原因上(但请记住我正在简化在这里)。
首先,快速绕行。以下表达式的类型是什么?
mempty
mempty
来自 Monoid
类。但是,与大多数方法不同,它不接受任何参数。那么 Haskell 如何知道将其实例化为哪种类型呢?以下所有内容都是正确的:
mempty == []
mempty == Sum 0
mempty == Any False
简而言之,Haskell(或者更确切地说是 GHC)推断表达式的类型,并使用该推断来选择正确的实现。有时,推理不起作用。例如在下面的表达式中:
print mempty
我们必须明确给出类型,如下所示:
print (mempty :: [Int])
@
符号是一种语法,用于应用通常可以推断出的任何类型。所以,在这种情况下,我们可以这样写:
print (mempty @[Int])
虽然它与 ::
不同:@
符号专门填充了 ghc 试图猜测的第一个类型空洞。所以我们同样可以在打印前应用它:
print @[Int] mempty
因此,您可以看到 @
是我们将类型应用于表达式的一种方式。不过,它真正让我们做的是从类型(轻松)获取值。例如:
{-# LANGUAGE TypeApplications, AllowAmbiguousTypes #-}
class TypeName a where
name :: String
instance TypeName Int where
name = "Hello, I'm an Int!"
instance TypeName Bool where
name = "Bool!"
name @Int
换句话说,我们可以让类型级别的程序产生值级别的结果。这就是 generic-lens 的用武之地。这个包将它用于字段。当您有如下类型时:
data Person
= Person
{ name :: String
, age :: Int
}
您可以制作两个镜头,一个名为 _name
,另一个名为 _age
(或其他名称)。 generic-lens 做的稍微聪明一点:它有一个函数(fieldLens
),你可以这样使用:
-- age lens
fieldLens @"age"
最后,我们需要 DataKinds
。传统上,类型级别只允许类型,这就是 @
符号处理的内容。不过,上面是一个字符串:解除此限制正是 DataKinds
所做的。
最后,从技术上讲,您不需要 DataKinds
来伪造上述行为。您可以再次使用类型。事实上,在 DataKinds
之前,人们习惯于做如下事情:
data AgeField = DontConstructMe
fieldLens @AgeField
关于haskell - generic-lens与DataKinds GHC扩展的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56088579/
以下示例是我现实生活中问题的简化版本。它似乎在某种程度上类似于 Retrieving information from DataKinds constrained existential types
我一直在自学类型级编程,并想编写一个简单的自然数加法类型函数。我的第一个版本如下: data Z data S n type One = S Z type Two = S (S Z) type fam
我在让 GHC 在一个应该很明显的地方推断出一个类型时遇到了问题。以下是演示问题的完整片段。 {-# LANGUAGE DataKinds, ScopedTypeVariables, KindSign
假设我有一个货币类型: data Currency = USD | EUR | YEN 和存储 int 的 Money 类型,并由给定的货币参数化(货币被提升为具有 DataKinds 扩展的种类)。
如果我有一个受有限 DataKind 约束的类型 {-# LANGUAGE DataKinds #-} data K = A | B data Ty (a :: K) = Ty { ... } 以及忘
使用 DataKinds,定义如下 data KFoo = TFoo 介绍种类KFoo :: BOX和类型 TFoo :: KFoo .为什么我不能继续定义 data TFoo = CFoo 这样CF
我从Basic Type Level Programming in Haskell学习Haskell的类型编程但是当它引入 DataKinds 扩展时,示例中有些东西似乎令人困惑: {-# LANGU
我有一个 Universe 类型和一个 Worker 类型。 worker 可以改变宇宙。我想要实现的目标是确保宇宙只能由来自该宇宙的 worker (而不是 future 或过去的 worker )
使用高级类型系统的东西。我想要命名 kind 和 a几个生成此类类型的类型构造函数: {-# LANGUAGE DataKinds #-} data Subject = New | Existing
我有一个常见的模式,其中有一个 [*] 类型的类型级列表,并且我想应用 * -> * 类型的类型构造函数> 到列表中的每个元素。例如,我想将类型 '[Int, Double, Integer] 更改为
我有这个代码片段,它使用了大量的 GHC 扩展: {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GA
我正在尝试找到对 DataKinds 扩展的解释,这对我来说是有意义的,因为我只读过 Learn You a Haskell 。是否有一个标准来源对我来说对我所学到的一点点有意义? 编辑:例如 doc
通过最近有关 HaskellDB 的帖子,我有动力再次研究 HList。由于我们现在在 GHC 中有 -XDataKinds,它实际上有一个异构列表的示例,因此我想研究 HList 与 DataKin
假设我有这个: data Animal = Dog | Cat :t Dog Dog :: Animal 很公平。 :k Dog :1:1: Not in scope: type constr
我正在尝试将 GADT 与 DataKinds 一起使用,如下所示 {-# LANGUAGE KindSignatures, DataKinds, GADTs #-} module NewGadt w
给定一个 ADT data K = A | B Bool DataKinds扩展允许我们将其提升为种类和类型/类型构造函数 K :: BOX 'A :: K 'B :: 'Bool -> K 有没有办
尝试使用 TypeLits 对数据类型进行 JSON 反序列化时,我遇到了以下问题: Couldn't match type ‘n’ with ‘2’ ‘n’ is a rigid type
因此,当我在使用 DataKinds 时尝试确定多态返回值的类型时,ghci 给了我一个有趣的错误。我有以下代码: {-# LANGUAGE DataKinds #-} {-# LANGUAGE Ki
我有一些这样的类型: data Currency = USD | EUR deriving (Show, Typeable) data Money :: Currency
所以,我终于找到了一个可以利用新的 DataKinds 的任务。扩展(使用 ghc 7.4.1)。这是Vec我正在使用: data Nat = Z | S Nat deriving (Eq, Show
我是一名优秀的程序员,十分优秀!