【发布时间】:2016-04-28 22:54:59
【问题描述】:
我有问题。我有一个数据类型 Thing,它本质上是 Maybe Doubles 或 Maybe Texts 的大记录。我想创建一个数据类型,即使某些字段可能是 Nothing,也可以捕捉在其上运行计算的想法。
data Computation a b = Computation
{ getInputs :: Thing -> a
computation :: a -> b
modifyThing :: b -> Thing -> Thing
}
基于输出 b,它很可能对应于事物中的某些字段,我想创建一个新事物。
modifyThing :: b -> Thing -> Thing
从 Thing 到 Maybe b 的计算可以分为两部分,加载变量和只接受数字或文本的计算。
getInputs :: Thing -> a
computation :: a -> b
以上几乎就是我想要的。在这种情况下,a 将是 (Maybe a1, Maybe a2..) 等等。这意味着在“计算”和 getInputs 我必须做类似的事情
getInputs t = \t -> ( getProp1 t , getProp2 t)
computation = \(m_a1, m_a2) -> do
a1 <- m_a1
a2 <- m_a2
return $ a1 + a2
我宁愿让计算看起来像
exampleComp a1 a2 = a1 + a2
然后做类似的事情
runComputation :: Thing -> Computation -> b
runComputation thing comp = magic (computation comp) ((getInputs comp) thing)
where magic = ???
问题是我不知道该怎么做
(Maybe a1, Maybe a2, ... , Maybe a_n)
到
a1 -> a2 -> ... -> a_n
如果任何 Maybe 是 Nothing,则返回 Nothing。我可以的
pure computation <*> m_a1 <*> m_a2 <*> m_a3
但是我怎样才能为任何类型的元组编写魔法呢?
附言
我正在考虑将计算写成
computation :: Thing -> b
并取消 getInputs,但它似乎会更加笨拙 供我测试和玩耍。这就是为什么我试图采用我上面描述的方法。你认为这是一个好主意吗?
已编辑
虽然不是针对我提出的特定问题的解决方案,但出于我想要做的事情的意图,我决定这样做
data Computation = Computation
{ getInputs :: Thing -> Maybe a
, computation :: a -> b
, modifyThing :: b -> Thing -> Thing
}
将是前进的最佳方式。这样我就不用担心元组了。
【问题讨论】:
-
你有什么理由不能使用可能的列表吗?
-
@Guvante 列表的一个缺点是它们是同质的——例如无法同时选择
Double-y 类型字段和Int-y 类型字段。 -
@user3550758 如果您找到解决方案,StackOverflow 的方法是将其写为答案,而不是将其包含在问题的编辑中。我鼓励你将你的“编辑”拆分成它自己的实体——如果它是你得到的最佳答案,甚至接受它。 (这在这里被认为是非常有礼貌甚至是可取的。)
标签: haskell