- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 vinyl图书馆,有一个RecAll
类型族,让我们要求部分应用的约束对于类型级别列表中的每个类型都是正确的。例如,我们可以这样写:
myShowFunc :: RecAll f rs Show => Rec f rs -> String
RecAll f rs c
在哪里
c
是未知的,我们知道
c x
包含
d x
(借用ekmett的
contstraints包的语言),我们怎样才能得到
RecAll f rs d
?
:&:
来自
Control.Constraints.Combine 的组合器
exists 中的模块包裹。 (注意:如果您安装了其他东西,该软件包将无法构建,因为它依赖于
contravariant
的 super 旧版本。不过,您可以复制我提到的一个模块。)有了这个,我可以得到一些非常漂亮的东西约束,同时最小化 typeclass broilerplate。例如:
RecAll f rs (TypeableKey :&: FromJSON :&: TypeableVal) => Rec f rs -> Value
RecAll f rs (TypeableKey :&: TypeableVal) => Rec f rs -> Value
import Data.Constraint
weakenAnd1 :: ((a :&: b) c) :- a c
weakenAnd1 = Sub Dict -- not the Dict from vinyl. ekmett's Dict.
weakenAnd2 :: ((a :&: b) c) :- b c
weakenAnd2 = Sub Dict
-- The two Proxy args are to stop GHC from complaining about AmbiguousTypes
weakenRecAll :: Proxy f -> Proxy rs -> (a c :- b c) -> (RecAll f rs a :- RecAll f rs b)
weakenRecAll _ _ (Sub Dict) = Sub Dict
Dict
作为我实际代码中的合格导入,这就是它提到
Constraint.Dict
的原因:
Table.hs:76:23:
Could not deduce (a c) arising from a pattern
Relevant bindings include
weakenRecAll :: Proxy f
-> Proxy rs -> (a c :- b c) -> RecAll f rs a :- RecAll f rs b
(bound at Table.hs:76:1)
In the pattern: Constraint.Dict
In the pattern: Sub Constraint.Dict
In an equation for ‘weakenRecAll’:
weakenRecAll _ _ (Sub Constraint.Dict) = Sub Constraint.Dict
Table.hs:76:46:
Could not deduce (RecAll f rs b)
arising from a use of ‘Constraint.Dict’
from the context (b c)
bound by a pattern with constructor
Constraint.Dict :: forall (a :: Constraint).
(a) =>
Constraint.Dict a,
in an equation for ‘weakenRecAll’
at Table.hs:76:23-37
or from (RecAll f rs a)
bound by a type expected by the context:
(RecAll f rs a) => Constraint.Dict (RecAll f rs b)
at Table.hs:76:42-60
Relevant bindings include
weakenRecAll :: Proxy f
-> Proxy rs -> (a c :- b c) -> RecAll f rs a :- RecAll f rs b
(bound at Table.hs:76:1)
In the first argument of ‘Sub’, namely ‘Constraint.Dict’
In the expression: Sub Constraint.Dict
In an equation for ‘weakenRecAll’:
weakenRecAll _ _ (Sub Constraint.Dict) = Sub Constraint.Dict
最佳答案
让我们首先回顾一下 Dict
和 (:-)
旨在使用。
ordToEq :: Dict (Ord a) -> Dict (Eq a)
ordToEq Dict = Dict
Dict
类型
Dict (Ord a)
带来约束
Ord a
进入范围,从中
Eq a
可以推导出(因为
Eq
是
Ord
的父类(super class)),所以
Dict :: Dict (Eq a)
是很好的类型。
ordEntailsEq :: Ord a :- Eq a
ordEntailsEq = Sub Dict
Sub
在参数的持续时间内将其输入约束带入范围,允许
Dict :: Dict (Eq a)
也可以很好地打字。
Dict
上的模式匹配将约束带入范围,
Sub Dict
上的模式匹配没有将一些新的约束转换规则纳入范围。事实上,除非输入约束已经在范围内,否则无法在
Sub Dict
上进行模式匹配。一点也不。
-- Could not deduce (Ord a) arising from a pattern
constZero :: Ord a :- Eq a -> Int
constZero (Sub Dict) = 0
-- okay
constZero' :: Ord a => Ord a :- Eq a -> Int
constZero' (Sub Dict) = 0
"Could not deduce (a c) arising from a pattern"
: 您尝试在
Sub Dict
上进行模式匹配, 但输入约束
a c
尚未在范围内。
RecAll f rs b
约束。那么,需要哪些部分,哪些部分缺失?我们来看看
RecAll
的定义.
type family RecAll f rs c :: Constraint where
RecAll f [] c = ()
RecAll f (r : rs) c = (c (f r), RecAll f rs c)
RecAll
是一个类型族,因此未经评估,具有完全抽象的
rs
, 约束
RecAll f rs c
是一个黑盒子,不能从任何较小的部分中得到满足。一旦我们专业
rs
至
[]
或
(r : rs)
,很明显我们需要哪些部分:
recAllNil :: Dict (RecAll f '[] c)
recAllNil = Dict
recAllCons :: p rs
-> Dict (c (f r))
-> Dict (RecAll f rs c)
-> Dict (RecAll f (r ': rs) c)
recAllCons _ Dict Dict = Dict
p rs
而不是
Proxy rs
因为它更灵活:如果我有一个
Rec f rs
,例如我可以用它作为我的代理
p ~ Rec f
.
(:-)
实现上面的一个版本。而不是
Dict
:
weakenNil :: RecAll f '[] c1 :- RecAll f '[] c2
weakenNil = Sub Dict
weakenCons :: p rs
-> c1 (f r) :- c2 (f r)
-> RecAll f rs c1 :- RecAll f rs c2
-> RecAll f (r ': rs) c1 :- RecAll f (r ': rs) c2
weakenCons _ entailsF entailsR = Sub $ case (entailsF, entailsR) of
(Sub Dict, Sub Dict) -> Dict
Sub
带来其输入约束
RecAll f (r ': rs) c1
在它的参数持续时间内进入范围,我们已经安排它包括函数体的其余部分。类型族的方程
RecAll f (r ': rs) c1
扩展到
(c1 (f r), RecAll f rs c1)
,因此它们也都被纳入范围。它们在范围内的事实允许我们在两个
Sub Dict
上进行模式匹配。 ,还有那两个
Dict
将它们各自的约束纳入范围:
c2 (f r)
, 和
RecAll f rs c2
.这两个正是目标约束
RecAll f (r ': rs) c2
扩展到,所以我们的
Dict
右边是很好的类型。
weakenAllRec
的实现,我们需要在
rs
上进行模式匹配以确定是否将工作委托(delegate)给
weakenNil
或
weakenCons
.但是自从
rs
在类型级别,我们不能直接对其进行模式匹配。
Hasochism论文解释了如何在类型级别上进行模式匹配
Nat
,我们需要创建一个包装器数据类型
Natty
.方式
Natty
有效的是,它的每个构造函数都由相应的
Nat
索引。构造函数,所以当我们对
Natty
进行模式匹配时值级别的构造函数,相应的构造函数也隐含在类型级别。我们可以为类型级列表定义这样的包装器,例如
rs
, 但恰好
Rec f rs
已经有与
[]
对应的构造函数和
(:)
,以及
weakenAllRec
的调用者无论如何,很可能会有一个躺在那里。
weakenRecAll :: Rec f rs
-> (forall a. c1 a :- c2 a)
-> RecAll f rs c1 :- RecAll f rs c2
weakenRecAll RNil entails = weakenNil
weakenRecAll (fx :& rs) entails = weakenCons rs entails
$ weakenRecAll rs entails
entails
的类型必须是
forall a. c1 a :- c2 a
,而不仅仅是
c1 a :- c2 a
,因为我们不想声称
weakenRecAll
适用于任何
a
调用者的选择,而是我们希望要求调用者证明
c1 a
包含
c2 a
对于每个
a
.
关于haskell - 通过蕴涵削弱黑胶唱片的 RecAll 约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29905159/
在 Haskell 中,类型声明使用双冒号,即 (::),如 not::Bool -> Bool。 但是在许多语法与 Haskell 类似的语言中,例如榆树、 Agda 、他们使用单个冒号(:)来声明
insertST :: StateDecoder -> SomeState -> Update SomeState SomeThing insertST stDecoder st = ... Stat
如果这个问题有点含糊,请提前道歉。这是一些周末白日梦的结果。 借助 Haskell 出色的类型系统,将数学(尤其是代数)结构表达为类型类是非常令人愉快的。我的意思是,看看 numeric-prelud
我有需要每 5 分钟执行一次的小程序。 目前,我有执行该任务的 shell 脚本,但我想通过 CLI 中的键为用户提供无需其他脚本即可运行它的能力。 实现这一目标的最佳方法是什么? 最佳答案 我想你会
RWH 面世已经有一段时间了(将近 3 年)。在在线跟踪这本书的渐进式写作之后,我渴望获得我的副本(我认为这是写书的最佳方式之一。)在所有相当学术性的论文中,作为一个 haskell 学生,读起来多么
一个经典的编程练习是用 Lisp/Scheme 编写一个 Lisp/Scheme 解释器。可以利用完整语言的力量来为该语言的子集生成解释器。 Haskell 有类似的练习吗?我想使用 Haskell
以下摘自' Learn You a Haskell ' 表示 f 在函数中用作“值的类型”。 这是什么意思?即“值的类型”是什么意思? Int 是“值的类型”,对吗?但是 Maybe 不是“值的类型”
现在我正在尝试创建一个基本函数,用于删除句子中的所有空格或逗号。 stringToIntList :: [Char] -> [Char] stringToIntList inpt = [ a | a
我是 Haskell 的新手,对模式匹配有疑问。这是代码的高度简化版本: data Value = MyBool Bool | MyInt Integer codeDuplicate1 :: Valu
如何解释这个表达式? :t (+) (+3) (*100) 自 和 具有相同的优先级并且是左结合的。我认为这与 ((+) (+3)) (*100) 相同.但是,我不知道它的作用。在 Learn
这怎么行 > (* 30) 4 120 但这不是 > * 30 40 error: parse error on input ‘*’ 最佳答案 (* 30) 是一个 section,它仍然将 * 视为
我想创建一个函数,删除满足第二个参数中给定谓词的第一个元素。像这样: removeFirst "abab" ( 'b') = "abab" removeFirst [1,2,3,4] even =
Context : def fib(n): if n aand returns a memoized version of the same function. The trick is t
我明白惰性求值是什么,它是如何工作的以及它有什么优势,但是你能解释一下 Haskell 中什么是严格求值吗?我似乎找不到太多关于它的信息,因为惰性评估是最著名的。 他们各自的优势是什么。什么时候真正使
digits :: Int -> [Int] digits n = reverse (x) where x | n digits 1234 = [3,1,2,4]
我在 F# 中有以下代码(来自一本书) open System.Collections.Generic type Table = abstract Item : 'T -> 'U with ge
我对 Haskell 比较陌生,过去几周一直在尝试学习它,但一直停留在过滤器和谓词上,我希望能得到帮助以帮助理解。 我遇到了一个问题,我有一个元组列表。每个元组包含一个 (songName, song
我是 haskell 的初学者,我试图为埃拉托色尼筛法定义一个简单的函数,但它说错误: • Couldn't match expected type ‘Bool -> Bool’
我是 Haskell 语言的新手,我在使用 read 函数时遇到了一些问题。准确地说,我的理解是: read "8.2" + 3.8 应该返回 12.0,因为我们希望返回与第二个成员相同的类型。我真正
当我尝试使用真实项目来驱动它来学习 Haskell 时,我遇到了以下定义。我不明白每个参数前面的感叹号是什么意思,我的书上好像也没有提到。 data MidiMessage = MidiMessage
我是一名优秀的程序员,十分优秀!