【发布时间】:2021-12-07 10:21:44
【问题描述】:
我最近定义了一个类型,我可能无法计算其字段:
data Foo = Foo {x, y :: Int, others :: NonEmpty Int}
data Input
computeX, computeY :: Input -> Maybe Int
computeOthers :: Input -> Maybe (NonEmpty Int)
现在,我可能会做的一件显而易见的事情就是使用liftA3:
foo :: Input -> Maybe Foo
foo i = liftA3 Foo (computeX i) (computeY i) (computeOthers i)
这很好用,但我认为将Foo 概括为也持有Maybes,然后将一种类型的Foo 转换为另一种类型可能会很有趣。在一些类似的情况下,我可以给 Foo 类型一个类型参数并派生 Traversable。然后在创建Foo (Maybe Int) 之后,我可以使用sequenceA :: Foo (Maybe Int) -> Maybe (Foo Int) 一次反转整个事情。但这在这里不起作用,因为我的函数没有给我NonEmpty (Maybe Int),它给了我Maybe (NonEmpty Int)。
所以我想我会尝试通过函子进行参数化:
data Foo f = Foo {x, y :: f Int, others :: f (NonEmpty Int)}
但问题是,我如何将Foo Maybe 变成Maybe (Foo Identity)?显然,我可以手动编写该函数:它与上面的 liftA3 内容同构。但是这种高阶类型是否有一些 Traversable 的相似之处,以便我可以对这个问题应用更通用的函数,而不是使用定制函数重新执行它?
【问题讨论】:
标签: haskell functor higher-kinded-types