功能组成表示法

Chr*_*ner 7 haskell composition do-notation

对于简单的函数组合,是否有"do notation"语法糖?

(即(.) :: (b -> c) -> (a -> b) -> a -> c)

我希望能够存储一些成分的结果供以后使用(同时仍然继续链.

如果可能的话,我宁愿不使用RebindableSyntax扩展.

我正在寻找这样的东西:

composed :: [String] -> [String]
composed = do
    fmap (++ "!!!")
    maxLength <- maximum . fmap length
    filter ((== maxLength) . length)

composed ["alice", "bob", "david"]
-- outputs: ["alice!!!", "david!!!"]
Run Code Online (Sandbox Code Playgroud)

我不确定这样的事情是否可能,因为早期函数的结果基本上必须通过"通过"maxLength的绑定,但我愿意听到任何其他类似的表达选项.基本上我需要收集信息,因为我通过合成以便以后使用它.

也许我可以用状态monad做这样的事情?

谢谢你的帮助!

编辑

这种事情有点起作用:

split :: (a -> b) -> (b -> a -> c) -> a -> c
split ab bac a = bac (ab a) a

composed :: [String] -> [String]
composed = do
    fmap (++ "!!!")
    split 
        (maximum . fmap length)
        (\maxLength -> (filter ((== maxLength) . length)))
Run Code Online (Sandbox Code Playgroud)

lef*_*out 5

实现类似目标的一种可能方式是箭头.基本上,在"存储插页式结果"中,您只是将信息流分解为组合链.这就是&&&(扇出)组合器的作用.

import Control.Arrow

composed = fmap (++ "!!!")
       >>> ((. length) . (==) . maximum . fmap length &&& id)
       >>> uncurry filter
Run Code Online (Sandbox Code Playgroud)

这绝对不是人类易于理解的代码.

状态monad似乎也允许相关的东西,但问题是状态类型是通过do块的monadic链固定的.这并不足以灵活地在整个构图链中获取不同类型的值.虽然肯定可以规避这一点(其中确实如此RebindableSyntax),但这也不是IMO的好主意.


She*_*rsh 2

正如leftaroundabout提到的,您可以使用Arrows来编写您的函数。但是, ghc Haskell 编译器有一个功能,即proc箭头的 - 表示法。它与众所周知的do- 表示法非常相似,但不幸的是,没有多少人意识到它。

使用proc-notation,你可以用下一种更可编辑和优雅的方式编写你想要的函数:

{-# LANGUAGE Arrows #-}

import Control.Arrow (returnA)
import Data.List     (maximum)

composed :: [String] -> [String]
composed = proc l -> do
    bangedL <- fmap (++"!!!")        -< l
    maxLen  <- maximum . fmap length -< bangedL
    returnA -< filter ((== maxLen) . length) bangedL
Run Code Online (Sandbox Code Playgroud)

这在ghci中按预期工作:

ghci> composed ["alice", "bob", "david"]
["alice!!!","david!!!"]
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣,可以阅读一些带有精美图片的教程,以了解什么是箭头以及这个强大功能的工作原理,以便您可以更深入地了解它:

https://www.haskell.org/arrows/index.html

https://en.wikibooks.org/wiki/Haskell/Understanding_arrows