English 中文(简体)
作为管道代表数据处理的框架
原标题:frameworks for representing data processing as a pipeline

大多数数据处理可以作为部件的管道,一个数据输入另一个数据。 典型的加工管道是:

撰稿人

作为启动这一讨论的一个oil,请允许我考虑在每一部分都成为标的的情况下,以目标为导向的执行这一管道。 <代码>handler 物体既是指reader,又指. .s>,且有run。 方法:

define handler.run:
  while (reader.has_next) {
    data = reader.next
    output = ...some function of data...
    writer.put(output)
  }

Schematically the dependencies are:

reader <- handler -> writer

现在,我想在读者和手里之间讨论一个新的管道部分:

reader | tweaker | handler | writer

在此业务处实施过程中,<代码>tweaker <代码>reader Object and the tweaker/code> 方法可能看起来像(某些假冒的辅助法):

define tweaker.has_next:
  return reader.has_next

define tweaker.next:
  value = reader.next
  result = ...some function of value...
  return result

I m finding that this is not a very composable abstraction. Some issues are:

  1. www.un.org/Depts/DGACM/index_spanish.htm 只能在<代码>handler左侧使用。 i.e. 我可以采用tweaker<>/code>的上述实施方式形成这一管道:

    读者: 牙齿

  2. 我想利用管道的相关财产,以便这一管道:

    撰稿人

可以表示:

reader | p

<代码p为管道handler > 作家。 在本业务处执行中,我必须部分地对<代码>handler进行即时处理。 物体

  1. Somewhat of a restatement of (1), the objects have to know if they "push" or "pull" data.

I m 寻找一个框架(不一定是业务处),用以建立处理这些问题的数据处理管道。

我将此附在<代码>Haskell和>>>功能式方案拟订上,因为我觉得功能式方案拟订概念在这方面可能有用。

作为一个目标,能够建立这样一个管道:

                     handler1
                   /          
reader | partition              writer
                             /
                     handler2

从某种角度看,Unixhell管道在以下执行决定中解决了许多问题:

  1. 管道部件在不同的过程中同步运行。

  2. 管道反对在“推器”和“制片人”之间传递数据;即阻断撰写数据太快的作者和试图读得太快的读者。

  3. 您使用特别连接器<代码>和t;>将被动部件(即文档)与管道连接起来。

我特别感兴趣的是,在代理人之间不使用校对或传递信息的做法。 或许这是这样做的最佳途径,但我想尽可能避免read。

感谢!

最佳回答

Yeah, arrows几乎肯定是你的男性。

I suspect that you are fairly new to Haskell, just based on the kinds of things you are saying in your question. Arrows will probably seem fairly abstract, especially if what you are looking for is a "framework". I know it took me a while to really grok what was going on with arrows.

因此,你可以看一看这一页,并说“谁,看着我想要的东西”,然后发现如何开始用arrow子解决问题。 因此,这里没有什么指导,因此,你知道你正在研究什么。

浏览不会解决你的问题。 相反,它们给你一个你能够用的语言来形容你的问题。 你可能发现,一些预先界定的arrow子将做些工作——一些 k子——但是,在你想要执行<>/em>一个arrow(预先界定的 ones只给你执行这些 the子)的时候,你用“数据处理器”表示什么意思。 作为一个几乎微不足道的例子,请允许我说,你希望以简单的职能执行你的数据处理。 请写:

newtype Proc a b = Proc { unProc :: a -> b }

-- I believe Arrow has recently become a subclass of Category, so assuming that.

instance Category Proc where
    id = Proc (x -> x)
    Proc f . Proc g = Proc (x -> f (g x))

instance Arrow Proc where
    arr f = Proc f
    first (Proc f) = Proc ((x,y) -> (f x, y))

这使您能够使用各种星号((***)(&&>(>>>>等,以及如果你做复杂的事,则 rather缩。 因此,正如丹尼尔·菲舍尔在评论中指出的,贵方在你提出的问题中所描述的管道可以构成:

reader >>> partition >>> (handler1 *** handler2) >>> writer

但是,冷静的是,这要靠的是一位加工商所说的话。 可以采用不同的处理器类型,以类似方式实施你提到的每个处理器:

newtype Proc  a b = Proc (Source a -> Sink b -> IO ())

然后,适当落实合并者。

因此,你正在研究的是:谈论堆肥过程的词汇,这种过程几乎是再利用的法典,但主要有助于指导你的想法,因为你在运用这些综合工具确定加工商定义时,对你来说是有用的。

我的第一个非部落Haskell项目之一,是执行一个;该项目是促使我真正开始理解Haskell思维方式的项目,这是我的方案拟订工作的一个主要转折点。 你们的这一项目是否会对你们同样?

问题回答

由于lazy evaluation,我们可以就Haskell的普通功能构成表示管道。 这里的一个例子是对档案中线最长长度的计算:

main = interact (show . maximum . map length . lines)

这里的一切都是普通职能,例如,

lines :: String -> [String]

但是,由于幻觉评价,这些功能只是按需要逐步处理投入,就像UNIX管道一样。

The e amountator Pack for Haskell is a good framework for this. 它界定了三种物体:

  1. Enumerators which produce data in chunks.
  2. Iteratees that consume chunks of data and return a value after consuming enough.
  3. Enumeratees which sit in the middle of the pipeline. They consume chunks and produce chunks, possibly with side effects.

这三类物体组成一个溪流处理管道,即便在一条管道(一旦完成,下一个管道就会出现)中,你甚至可以有多个点和点子。 从零件中写出这些物体之一可能很复杂,但有许多综合器可用于将常规职能变成数据流处理器。 例如,该输油管的特征是从中转至上,功能为<代码>toUpper,然后写上:

ET.enumHandle stdin $$ ET.map toUpper =$ ET.iterHandle stdout

where the module Data.Enumerator.Text has been imported as ET.

Yesod 框架采用conduit包装。

在贾瓦、春雷克和阿帕奇·卡迈勒,正如其他人提到的那样,你想要做些什么,请允许我介绍非汉语。

例如,在阿帕帕奇·卡姆尔,数据通过交换处理(因为数据主要用于电文处理这一术语),以及你在整个过程中需要获得的财产,将数据储存在交易所的特性中(地图和图;String, Object>)。 这一进程是一条路线,你可以确定几个次路线,将一些步骤分成一个步骤,并向它提供名字。

就反应堆而言,它在 Java采用被动的方案拟订模式,并处理单一校对的任务。 共同的返回类型是莫诺(单一物体)或奢侈(收集物体),使用管道。

首先,从打脚石到管道,并非易事,但经过一段时间后,你将难以回头。





相关问题
Euler Problem in Haskell -- Can Someone Spot My Error

I m trying my hand at Euler Problem 4 in Haskell. It asks for that largest palindrome formed by multiplying two three-digit numbers. The problem was simple enough, and I thought my Haskell-fu was up ...

How does foldr work?

Can anybody explain how does foldr work? Take these examples: Prelude> foldr (-) 54 [10, 11] 53 Prelude> foldr (x y -> (x+y)/2) 54 [12, 4, 10, 6] 12.0 I am confused about these executions....

Efficient queue in Haskell

How can I efficiently implement a list data structure where I can have 2 views to the head and end of the list, that always point to a head a tail of a list without expensive calls to reverse. i.e: ...

Problem detecting cyclic numbers in Haskell

I am doing problem 61 at project Euler and came up with the following code (to test the case they give): p3 n = n*(n+1) `div` 2 p4 n = n*n p5 n = n*(3*n -1) `div` 2 p6 n = n*(2*n -1) p7 n = n*(5*n -3)...

Ways to get the middle of a list in Haskell?

I ve just started learning about Functional Programming, using Haskel. I m slowly getting through Erik Meijer s lectures on Channel 9 (I ve watched the first 4 so far) and in the 4th video Erik ...

haskell grouping problem

group :: Ord a => [(a, [b])] -> [(a, [b])] I want to look up all pairs that have the same fst, and merge them, by appending all the list of bs together where they have the same a and discarding ...

Closest equivalent to subprocess.communicate in Haskell

I want to do a popen() / python s subprocess.communicate from Haskell - start a program, give it stdin, and get its stdout/stderr. What s the most direct / Haskellish way to do this?