2016-02-01 112 views
1

是否可以在Haskell中操作嵌套函数组合,以这种方式在构图之前对每个函数执行一些处理?Haskell嵌套堆肥函数

假设像(lines . unlines . words) "Testing Haskell composition"这样的嵌套合成(它没有意义,它只是一个随机的例子)。 我想在执行lines,unlineswords之前做一些事情。事情是这样的假码:

performComposition :: [functions] -> returnValue 
performComposition [] =() 
performComposition (f:fs) = do something 
          f (performComposition fs) 

是否有可能,哪怕是要创建一个新的运营商?

EDIT(2016年2月17日)

我没有提到,我想做点什么的最后一个功能有所不同。在上面的示例中,words函数在执行之前会做与其他函数不同的操作。

我找到的解决方案详述如下。

+0

你可以写你自己的* *组成运营商 - 但副作用的'做something'部分气味... – Carsten

+1

你能成为在你的例子中更具体一点?你想用这个做什么?你试图解决什么问题,通过简单地使用类似'run before before before >> return computation >> =(\ val - > after >> return val)''之类的东西就不能解决这个问题。这是一个单子函数,所以它不能用来代替'运算'。 – bheklilr

+0

等待:你想要这个:'performComposition [] = id; performComposition(f:fs)= f。 performComposition fs'?但是,这只是简单地将构图推广到函数列表(这是一个“折叠”)。 – Bakuriu

回答

0

类似的问题有几个答案可以找到here。据我所知,没有构建功能组合分裂的机制。你可以添加某种构造(链接中有更多细节),但它会打破haskells的功能纯度,因为函数分解应该提供不同的结果,其构图规则不同a=f.(g.h)b=(f.g).h。 (但它具有相同的功能,做相同的转换,所以它应该每次都返回相同的东西)

+2

这看起来像一个评论。如果你认为这个问题是重复的,你应该投票/重复标记。 – Bakuriu

1

我发现我的问题的解决方案是创建类似于三元运算符的东西。 This link是必不可少的。

所以,解决我的问题的一个简单的演示是:

(>=>) :: a -> (a->b) -> b -- first operator 
x >=> y = doSomething1 --fake code 
      y x 

(¨¨) :: a -> (a->b) -> b -- second operator 
x ¨¨ y = doSomething2 --fake code 
     y x 

infixl 0 >=> 
infixl 1 ¨¨ 

times2 :: Int -> Int 
times2 x = x*2 

plus2 :: Int -> Int 
plus2 x = x+2 

plus3 :: Int -> Int 
plus3 x = x+3 

main = putStrLn $ show (3 ¨¨ plus2 ¨¨ times2 >=> plus3)