我试图为无形的通过和实现定义一个Monad
(scalaz) 。第一个问题是trait 不是类型构造函数,但可以用类型 lambdas 解决,很简单,但我找不到正确的实现,我想我需要一些类型的函数和一些技巧,但那一面无形对我来说仍然是黑暗的。所有的函数都是一个 Monad,比如简单的 List,所以可以从 Scalaz 中实现一个吗?HList
point
bind
HList
point
bind
Poly1
Aux/Mapper
HList
1 回答
幺半群是具有一些遵守特定规律的操作的集合。您在考虑哪些因素是可能的HListM[A]
?如果您声明HListM[A] = HList
,即 any HList
,那么您很快就会发现您不能map
使用f: A => B
,除非将所有map
s 视为identity
并且您已经重新发明了相当无趣的 monad Id
(带有一些额外但惰性的居民)。
我们可以使用该类型创建一个 monad HListM[A] = A :: ... :: A :: HNil
(尽管在 Scala 中实际表达该类型也是一个挑战——您需要一个辅助 trait trait CopiesOf[N <: Nat, A] {type Out <: HList
}、 implicit
s 来提供它的实例,然后是一个存在性来实际编写它(CopiesOf[N, A]#Out forSome {type N <: Nat}
))。为此编写 monad 操作是可能的,尽管您需要像Prepend
在操作点一样需要无形的辅助类,因为在 Scala 中没有真正的方法来表达“forall”类型 - 您可以为_0
and声明您的类型的实例Succ[N]
,但是没有办法向编译器证明 any 有一个实例N <: Nat
,你只需要在需要使用它们时要求隐式实例。
但是经过大量工作后,您最终会得到与List[A]
;同构的东西。为什么不只List[A]
用于这种情况?