大多数数据处理可以被设想为组件的流水线,一个组件的输出馈入另一个组件的输入.典型的处理管道是:
reader | handler | writer
Run Code Online (Sandbox Code Playgroud)
作为开始讨论的一个衬托,让我们考虑一个面向对象的实现这个管道,其中每个段都是一个对象.该handler对象包含对reader和writer对象的引用,并具有如下所示的run方法:
define handler.run:
while (reader.has_next) {
data = reader.next
output = ...some function of data...
writer.put(output)
}
Run Code Online (Sandbox Code Playgroud)
示意性依赖关系是:
reader <- handler -> writer
Run Code Online (Sandbox Code Playgroud)
现在假设我想在读者和处理程序之间插入一个新的管道段:
reader | tweaker | handler | writer
Run Code Online (Sandbox Code Playgroud)
同样,在这个OO实现中,tweaker将是reader对象的包装器,并且tweaker方法可能看起来像(在一些伪命令性代码中):
define tweaker.has_next:
return reader.has_next
define tweaker.next:
value = reader.next
result = ...some function of value...
return result
Run Code Online (Sandbox Code Playgroud)
我发现这不是一个非常可组合的抽象.一些问题是:
tweaker只能在左侧使用handler,即我不能使用上面的实现tweaker来形成这个管道:
读者| 处理程序| tweaker | …
haskell functional-programming pipeline pipe data-processing
似乎Haskell已经围绕monad建立了几个命名约定.
例子:
T到最后获得monad变压器的名称(例如Reader- > ReaderT)runXXX以执行单子计算(例如runST,runReader)liftXXX 对于各种价值观 XXX还有其他命名约定吗?
我一直在浏览http://www.algorithm.com.au/downloads/talks/monads-are-not-scary/monads-are-not-scary-chak.pdf上的幻灯片.
和约.通过甲板75%的方式有一个要点"重新定义IO以简化调试!"
这看起来像一个非常有趣的想法!有人可以举一个说话者谈论的实际例子吗?
更新:运行ghc-pkg检查报告:
~: ghc-pkg check
WARNING: cache is out of date: /Library/Frameworks/GHC.framework/Versions/7.0.3i386/usr/lib/ghc-7.0.3/package.conf.d/package.cache
use 'ghc-pkg recache' to fix.
~: ghc-pkg recache
Run Code Online (Sandbox Code Playgroud)
在那之后,cabal似乎更快乐了!
尝试安装yesod但第一次安装失败的原因是:
Building attoparsec-0.9.1.1...
Building library...
Creating dist/build (and its parents)
/usr/bin/ghc --make -package-name attoparsec-0.9.1.1 -hide-all-packages -fbuilding-cabal-package -i -idist/build -i. -idist/build/autogen -Idist/build/autogen -Idist/build -optP-DAPPLICATIVE_IN_BASE -optP-include -optPdist/build/autogen/cabal_macros.h -odir dist/build -hidir dist/build -stubdir dist/build -package-id base-4.3.1.0-167743fc0dd86f7f2a24843a933b9dce -package-id bytestring-0.9.1.10-77e44adc4117472276bab802bea3c036 -package-id containers-0.4.0.0-18deac99a132f04751d862b77aab136e -package-id deepseq-1.1.0.2-09b3aed0c4982bbc6569c668100876fa -O -Wall -XHaskell98 -XCPP Data.Attoparsec Data.Attoparsec.Char8 Data.Attoparsec.Combinator Data.Attoparsec.FastSet Data.Attoparsec.Lazy Data.Attoparsec.Number Data.Attoparsec.Zepto Data.Attoparsec.Internal Data.Attoparsec.Internal.Types
<command line>: cannot satisfy -package-id deepseq-1.1.0.2-09b3aed0c4982bbc6569c668100876fa
(use -v …Run Code Online (Sandbox Code Playgroud) 我想知道为什么在这种情况下的:sprint报告xs = _:
Prelude> xs = map (+1) [1..10]
Prelude> length xs
10
Prelude> :sprint xs
xs = _
Run Code Online (Sandbox Code Playgroud)
但在这种情况下不是:
Prelude> xs = map (+1) [1..10] :: [Int]
Prelude> length xs
10
Prelude> :sprint xs
xs = [_,_,_,_,_,_,_,_,_,_]
Run Code Online (Sandbox Code Playgroud)
注:我正在ghci用-XNoMonomorphismRestriction.是否与xs第一种情况下的多态性类型有关,而在第二种情况下不是多态性的事实?我想知道内部发生了什么.
我写了这篇文章,以便我可以提前终止monadic折叠:
myfoldM :: (Monad m) => (a -> b -> m (Maybe a)) -> a -> [b] -> m (Maybe a)
myfoldM _ a [] = return $ Just a
myfoldM f a (x:xs) = do ma <- f a x;
case ma of
Nothing -> return Nothing
Just a' -> myfoldM f a' xs
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种更优雅的方式来表达这个或者库中是否存在类似的东西.当然也有类似的版本替换Maybe使用Either.
更新......这是基于PetrPudlák答案的完整解决方案:
import Control.Monad (foldM,Monad,mzero)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Trans.Class (lift)
myfoldM' :: (Monad m) => (a -> b -> MaybeT …Run Code Online (Sandbox Code Playgroud) 这种形式的模式匹配称为:Option{..} <- ...例如,因为它在这里使用:
data Option = Option { cabal :: Maybe String , noStylish :: Bool }
...
main = do
Option{..} <- cmdArgs defOption
cabp <- case cabal of
Nothing -> do
...
Run Code Online (Sandbox Code Playgroud)
它似乎重新定义cabal和nostylish.在模式匹配之前cabal有类型Option -> Maybe String但在类型之后Maybe String.
此示例来自最近上传的包cabal2ghci.
是否可以"堆叠"cabal沙箱或指定"package.d"搜索路径?
我想将常用的软件包安装到项目可以使用但不更新的公共沙箱中.
文件中有一个world-file参数cabal.sandbox.config,但我在Cabal源代码中找不到对它的引用.
有没有办法argv[0]在Haskell程序中设置(比如用ghc编译的程序)?
我在System.Environment中找到了getProgName和withProgName函数,但它似乎没有改变什么ps报告(Ubuntu).
import System.Environment
main =
do name <- getProgName
putStrLn $ "Hello, my name is " ++ name
withProgName "other" $ do
newname <- getProgName
putStrLn $ "Name now set to " ++ newname
putStrLn "What is your name: "
-- allow time to run ps
ans <- getLine
putStrLn $ "Pleased to meet you, " ++ ans
Run Code Online (Sandbox Code Playgroud) 鉴于CODE参考,是否有可能:
通常我们通过指定源代码在perl中创建子例程,然后解析源代码并将其转换为解析树.
我想编写一个perl函数,它可以通过指定其解析树来创建子例程,并且该解析树可以从某个其他子例程的另一个解析树派生.
可能?