我怎么说B
的一个示例可以为那些A
的示例创建,而不为其他m
创建呢?
-- A.hs
module A where
class A m -- m :: * -> *
-- B.hs, totally unrelated to A
module B where
class B m
-- Utilities.hs
module Utilities where
given A m then instance B m -- like given in Scala 3
请注意,我 * 不 * 想说:
class A => class B -- B requires A
B
不知道也不应该知道A
。在class
级别,B
与A
无关。B
仅根据其最小完整定义(在其where
子句之后表示)进行定义(此处未显示),并且不了解A
或任何其他类。实际上,B
是独立的。
我也不想说:
instance A m => B m -- *all* m are B, this requires A m as well
-- actually this errors out with a "constraint is no smaller than head"
-- which is fixed by `newtype`ing around the `m` in `B`
-- but this is besides the point
这里说 allm
s是B
s,并且要求所有m
也是A
s,这不是真的,也不是我想说的,这不是Scala代码行(blow)所说的。
我想说的正是:有一个B
,它定义了某个接口,还有一个完全不相关的A
,B
不是根据A
定义的,在它的 definition 站点也不需要A
。现在,其他人沿着并且知道一种方法,如果m
有一个A
的示例,就可以为m
创建一个B
的示例。
在Scala中,我可以很容易地说:
implicit def fromA[M: A]: B[M] = ...
也就是说,* 如果 * 您可以证明M
是A
(在Scala中,这是通过将implicit
A[M]
引入作用域来实现的),然后我可以自动为M
构造B
示例。特别是,这不会在所有M
上强制B
,并且如果A[M]
在某些M
中不成立,则不是错误。你可以自己为M
构造B
,上面的(第二个)Haskell代码并不等同于Scala代码。
我想在 haskell 找一个
- 更新 * 显然在Haskell没有办法做到这一点
- 更新2* 这是问题Can't code my component in a tagless-final way / using type classes and instances背后的具体案例
3条答案
按热度按时间disbfnqx1#
你想做的事不能做 *;所有已经有
A
示例的东西也必须显式地作为B
示例列出。2但是你可以最小化样板文件。如果控制
B
的定义,则可以使用DefaultSignatures
:如果你不控制
B
的定义,你可以做一个 Package 器newtype并使用DerivingVia
,如果你也不控制已经是A
示例的类型的定义,可能会抛出StandaloneDeriving
。另见:
IncoherentInstances
来做一些扭曲,但是它们很脆弱,我强烈建议不要用它们。yqlxgs2m2#
不,这是你想要的。它说:“每当某个东西是
A
的示例时,使用这些规则使它成为B
的示例。你可能还需要FlexibleContexts
来解决约束问题。FlexibleContexts
是许多Haskell扩展之一,它最终是无害的,每天都在许多项目中使用。这就是你所想的,它说:“为了成为
B
的示例,它必须已经是A
的示例,当你第一次声明class
时,你声明了这个约束,当你对一个示例施加约束时,它量化了这个示例。ig9co6j13#
在Scala中,我可以很容易地说:
我想在 haskell 找一个
scala
implicit def fromA[M: A]: B[M] = ...
表示,如果数据类型M
是类型类A
的示例,那么它就是类型类B
的示例。的直译
https://scastie.scala-lang.org/DmytroMitin/Nz1BZQwEQfu6HFQpzBKNww/7
是
https://ideone.com/iZtAyh
这里我定义了三种数据类型
C
、D
、E
。C
是A
的示例(因此自动是B
的示例),D
是B
的示例,但不是A
的示例,E
不是其中任何一种的示例。所以,要么你想在Haskell中使用
instance A m => B m
,要么你不想在Scala中使用implicit def fromA[M[_]: A]: B[M] = ???
。另一方面,这个
https://scastie.scala-lang.org/DmytroMitin/SpuuQYfqQZibQk6EiVQnHw
在Haskell中是不可能
https://ideone.com/mXXug0
使用
OVERLAPPING
/OVERLAPPABLE
无法修复此问题。How to implement
Constraint
reflection? [Ad-Hoc polymorphism based on available Constraints]Take action based on a type parameter's typeclass?