测序与纯函数结合

Mag*_*ist 8 haskell

我经常发现自己想要将常规函数插入"绑定"序列中.就像在这个人为的例子中一样:

getLine >>= lift (map toUpper) >>= putStrLn
Run Code Online (Sandbox Code Playgroud)

我需要定义提升功能lift :: (a -> b) -> a -> m b才能使其工作.问题是我不知道这样的功能,而Hoogle似乎也没有.我觉得这很奇怪,因为这对我来说很有意义.

现在,可能有其他方法可以使这项工作,但我喜欢无点样式代码允许我在一个通道中扫描线以找出正在发生的事情的方式.

let lift f x = return (f x) in
getLine >>= lift (map toUpper) >>= putStrLn
Run Code Online (Sandbox Code Playgroud)

我的问题归结为:我错过了什么或者怎么没有像升力机这样的功能.我在Haskell的经历仍然非常有限,所以我假设大多数人以不同的方式解决这个问题.有人可以向我解释解决这个问题的惯用方法.

Dan*_*ner 18

有三种惯用方式.

  1. 不要使用bind; 使用您的Hoogle搜索中的第一个匹配:

    liftM (map toUpper) getLine >>= putStrLn
    
    Run Code Online (Sandbox Code Playgroud)

    有各种各样的替代拼写liftM,例如fmap(<$>).

  2. 内联lift您定义的函数:

    getLine >>= return . map toUpper >>= putStrLn
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用monad定律融合选项2中的最后两个绑定:

    getLine >>= putStrLn . map toUpper
    
    Run Code Online (Sandbox Code Playgroud)

  • `putStrLn.map toUpper = << getLine`看起来非常整洁.我喜欢使用`= <<`,因为它类似于函数应用程序. (4认同)