【发布时间】:2011-08-15 23:38:39
【问题描述】:
我正在尝试编写一个arrow 转换器,它采用常规函数,并将它们转换为抽象值的计算。如果我们有一个“源”箭头,
f :: Int -> Int
f x = x + 1
那么目标是让 f 处理提升的 [sic?] 抽象值类型,在这个例子中
f' :: AV Int -> AV Int
f' (Const x) = Const (f x)
-- pass along errors, since AV computation isn't always defined
-- or computable in the case of errors
f' (Error s) = Error s
-- avRep = "abstract representation". Think of symbolic math manipulation or ASTs.
f' (Abstract avRep) = AVRepPlus avRep (AVRepConst 1)
然而,为了成功地实现这个箭头,需要提升几个类型,以便在任意深度具有具有一些具体值和一些抽象值的异构数据结构。我最终做的是为常规的 haskell 构造函数添加特殊类型,例如如果
g = uncurry (+) -- i.e. g (x, y) = x + y
然后我为元组构造函数 (,) 添加一个抽象表示,
AVTuple :: AV a -> AV b -> AV (a, b)
g 的代码被提升到 [展开一点],
g' (AVTuple (AVConst a) (AVConst b)) = (AVConst (g (a, b)))
g' (AVTuple (AVError e) _) = (AVError e)
-- symmetric case here, i.e. AVTuple _ (AVError e)
g' (AVTuple a@(AVTuple _ _) b) = -- recursive code here
AVEither 也需要这样做。这最终会成为很多案例。有什么好办法吗?
我是 Haskell 新手,所以请发给我参考资料或半详细的解释;可能我读过的最接近的东西是 SYBR 论文(废弃你的样板革命)第 1-3 节。
非常感谢!
【问题讨论】:
-
箭头在这里可能不是很有用。 Functor-Applicative-Monad 类集共享一个操作 fmap(对于 Monad 称为 liftM,对于 Applicative 称为 liftA),它将类型转换函数映射到 Functor“内部”的一个或多个元素上。箭头是一种非常通用的结构,因此不支持这样的操作。
-
stephen tetley似乎是正确的,Arrow作为一个类型类,不是你想要的。不过,我无法清楚地遵循您的目的。请注意,f'定义的前两位建议将AV a s定义为Error s | Concrete a。这是Either类型,您定义f'的那些行使其成为我们都使用的Either的标准fmap f。也许对不朽的 Typeclassopedia (haskell.org/wikiupload/8/85/TMR-Issue13.pdf) 的研究会让你更容易地交流你的目的?同样,我只是在开发一点stephen tetleys 评论。
标签: generics haskell types arrows algebraic-data-types