- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我们有一些类 Foo
这样 Foo f
的实例为我们提供实现 Functor f
所需的一切, Foldable f
和 Traversable f
.为避免重复实例,可以见证 Foo
之间的这种关系和 Functor, Foldable, Traversable
在新类型包装下:
type Foo :: (Type -> Type) -> Constraint
class Foo f
where
{- ... -}
type FoonessOf :: (Type -> Type) -> Type -> Type
newtype FoonessOf f a = FoonessOf (f a)
instance Foo f => Functor (FoonessOf f)
where
fmap = _
instance Foo f => Foldable (FoonessOf f)
where
foldMap = _
instance Foo f => Traversable (FoonessOf f)
where
traverse = _
现在假设我们有一些类型构造函数:
data Bar a = Bar {- ... -}
这样有一个:
instance Foo Bar
where
{- ... -}
我们想装备
Bar
其“
Foo
-ness”所暗示的实例。由于
Bar a
是
Coercible
至
FoonessOf Bar a
,我们希望能够导出实例
via
FoonessOf Bar
:
deriving via (FoonessOf Bar) instance Functor Bar
deriving via (FoonessOf Bar) instance Foldable Bar
这对于诸如
Functor
之类的类型类很有效。和
Foldable
不幸的是,当我们尝试对
Traversable
做同样的事情时,事情出错了:
[typecheck -Wdeferred-type-errors] [E] • Couldn't match representation of type ‘f1 (Foo Bar a1)’
with that of ‘f1 (Bar a1)’
arising from a use of ‘ghc-prim-0.6.1:GHC.Prim.coerce’
NB: We cannot know what roles the parameters to ‘f1’ have;
we must assume that the role is nominal
• In the expression:
ghc-prim-0.6.1:GHC.Prim.coerce
@(Foo Bar (f a) -> f (Foo Bar a)) @(Bar (f a) -> f (Bar a))
(sequenceA @(Foo Bar)) ::
forall (f :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep
-> TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep)
(a :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep).
Applicative f => Bar (f a) -> f (Bar a)
In an equation for ‘sequenceA’:
sequenceA
= ghc-prim-0.6.1:GHC.Prim.coerce
@(Foo Bar (f a) -> f (Foo Bar a)) @(Bar (f a) -> f (Bar a))
(sequenceA @(Foo Bar)) ::
forall (f :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep
-> TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep)
(a :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep).
Applicative f => Bar (f a) -> f (Bar a)
When typechecking the code for ‘sequenceA’
in a derived instance for ‘Traversable Bar’:
To see the code I am typechecking, use -ddump-deriv
In the instance declaration for ‘Traversable Bar’
——————————————————————————————————————————————————————————————————————————————
...
所以我的问题是:
Traversable Bar
提出其他一些派生方案? ? Traversable
进行一些修改?可以通过新类型派生的类? 最佳答案
我怀疑1.的答案是:不,情况无法挽救,不可能获得Traversable
的实例。使用 DerivingVia
.
就 2. 而言,尝试在更简单的上下文中重现问题很有用。考虑以下:
-- Remember to turn on ScopedTypeVariables!
data A = A
newtype B = B A
a :: forall f. f A -> f A
a = id
b :: forall f. f B -> f B
b = coerce $ a @f
看起来这应该可行,但是唉:
[typecheck -Wdeferred-type-errors] [E] • Couldn't match representation of type ‘f A’ with that of ‘f B’
arising from a use of ‘coerce’
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
• In the expression: coerce $ a @f
In an equation for ‘b’: b = coerce $ a @f
• Relevant bindings include
b :: f B -> f B
F :: Type -> Type
如果有
Representational F
的实例,则具有“代表性”角色的参数, 在哪里:
type Representational :: (Type -> Type) -> Constraint
type Representational f = forall x y. Coercible x y => Coercible (f x) (f y)
否则,
F
的参数是非代表性的。
Representational f
直接地:
b' :: forall f. Representational f => f B -> f B
b' = coerce $ a @f
现在进行类型检查。这表明了一种可能的方法来调整
Traversable
typeclass 使其可通过强制导出。
Traversable
的类型操作
sequenceA
:
class Traversable t
where
sequenceA :: forall f. Applicative f => forall a. t (f a) -> f (t a)
{- ... -}
注意:有那个讨厌的
forall f
再次,意思是
f
被认为具有名义角色的类型参数。
DerivingVia
要做的是尝试
coerce
之间:
sequenceA @T1 :: forall f. Applicative f => forall a. T1 (f a) -> f (T2 a)
和:
sequenceA @T2 :: forall f. Applicative f => forall a. T2 (f a) -> f (T2 a)
尽管
T1
(
FoonessOf Bar
) 和
T2
(
Bar
) 被“参数化”强制,这种强制将失败,因为整个操作的强制最终将分解为类型检查器提示的强制:
Couldn't match representation of type
‘f1 (Foo Bar a1)’
with that of
‘f1 (Bar a1)’
这不起作用,因为
f
的参数被认为具有名义作用,正如我们所讨论的。
Representational f
:
type Traversable' :: (Type -> Type) -> Constraint
class Traversable' t
where
traverse :: (Representational f, Applicative f) => (a -> f b) -> t (f a) -> f (t b)
现在我们终于可以推导出
Traversable'
的实例了。通过
FoonessOf Bar
:
instance Foo f => Traversable' (FoonessOf f)
where
traverse = _
deriving via (FoonessOf Bar) instance Traversable' Bar
关于haskell - 是否可以通过另一个类型构造函数派生 Traversable 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68720357/
在 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
我是一名优秀的程序员,十分优秀!