从构造函数中拉出数据

时间:2016-11-01 03:36:56

标签: haskell

我对Haskell来说是全新的。

我有几层信息。每个图层都以独特的方式计算,但在输出中我只列出了类型元素。

layer1 :: MyData -> [Element1]
layer1 mydata = unique calculations

layer2 :: MyData -> [Element2]
layer2 mydata = even more unique calculations, using layer1

layer3 :: MyData -> [Element3]
layer3 mydata = completely genious layer of profound information
.....

所以这里我的N个函数不能被参数化并且应该保持分离。

然后我想在这些层上运行一堆类似的函数。

我可能会以一种简单的方式做到这一点

transform1 :: MyData -> [Int]
transform1 mydata = zipWith f (layer1 mydata) constList
transform2 :: MyData -> [Int]
transform2 mydata = zipWith f (layer2 mydata) constList
transform3 :: MyData -> [Int]
transform3 mydata = zipWith f (layer3 mydata) constList
......

但在这里显然是邀请某种统一。喜欢

universalTransform :: Layer -> [Int]
universalTransform layer = zipWith f layer constList

确定。所以现在我需要进行Layer抽象

data Layer = Lay1 [Element1] | Lay2 [Element2] | Lay3 [Element3]
data LayerName = Lay1Name | Lay2Name | Lay3Name

然后我需要制作一个调度收集器

take :: LayerName -> MyData -> Layer
take lname mydata = case lname of
  Lay1Name -> Lay1 (layer1 mydata)
  Lay2Name -> Lay2 (layer2 mydata)
  Lay3Name -> Lay3 (layer3 mydata)

不知何故,它变得越来越大,最糟糕的问题是我的zipWith f想要一个清单。在universalTransform layer中,不是列表。它是Layer抽象。我试图从[ElementsX]内部免费Layer,但没有成功。

我知道我正朝着错误的方向前进。

所以:我怎么能做到统一,但是以适当的方式,而不是......呃...我自己。

1 个答案:

答案 0 :(得分:3)

正如Alexis King指出的那样,你不需要Layer类型来抽象转换。只需让你的函数取f并将图层函数作为参数。那样,你就来自......

transform1 :: MyData -> [Int]
transform1 mydata = zipWith f (layer1 mydata) constList

... to(让我们说constList的类型是[Foo]):

transform :: (a -> Foo -> Int) -> (MyData -> [a]) -> MyData -> [Int]
transform f layer mydata = zipWith f (layer mydata) constList

如果你翻转transform的参数顺序,这个f就会变得更容易了:

transform :: (Foo -> a -> Int) -> (MyData -> [a]) -> MyData -> [Int]
transform f layer mydata = zipWith f constList (layer mydata)

现在很容易不明确提及mydata(最后一步可能是品味问题,但我最喜欢这种方式):

transform :: (Foo -> a -> Int) -> (MyData -> [a]) -> MyData -> [Int]
transform f layer = zipWith f constList . layer

transform与您使用Layer进行推测的主要区别在于,使用此解决方案,您不仅限于创建图层的三种方式,由{{1 }}。然而,鉴于你如何陈述你的问题,我猜你首先并不是真的想要这样的限制。

PS:如果你真的想要一些类似于你的LayerName提案的东西(这也是我强烈怀疑你实际上并不需要的东西),你可能会有更好的运气......

Layer

...加上一个图层生成函数(实际上会生成一个列表!):

data Element = Elem1 Element1 | Elem2 Element2 | Elem3 Element3

您提供的功能toLayer :: LayerName -> MyData -> [Element] 将负责对zipWith进行案例分析:

Element