lhc*_*tti 2 monads lambda haskell
我知道我可以使用函数monad来实现类似下面的构造(我在多个调用中重用参数而不显式引用它):
compute_v0 :: String -> String
compute_v0 = do
x <- length -- (using the argument implicitly here)
top <- head -- (and here)
return (replicate x top)
Run Code Online (Sandbox Code Playgroud)
上述函数的结果是:compute "1234"将是"1111"
我的问题是:在执行do块之前如何将变换应用于'hidden'参数(想象一下我想将"abcd"附加到列表中).
我的第一个解答:
compute_v1 :: String -> String
compute_v1 = compute_v1' . (++ "abcd")
compute_v1' ::String -> String
compute_v1' = do
x <- length
top <- head
return (replicate x top)
Run Code Online (Sandbox Code Playgroud)
现在的结果compute "1234"是"11111111".这实际上完成了工作,但我宁愿尝试将其全部定义在一个简洁的代码块中.
最接近我可以实际包含转换,同时仍然保持代码(v0)的样式是这一个:
compute_v2 :: String -> String
compute_v2 = (++ "abcd") >>= \r -> do
let x = length r
let top = head r
return $ replicate x top
Run Code Online (Sandbox Code Playgroud)
但是我仍然需要包含一个lambda,使用很多let绑定并显式引用lambda参数.是否有更好的方法来实现这样的结构?
由于所有Monad实例都有Functor实例和函数实例Functorhas fmap = (.),您可以拥有
compute :: String -> String
compute = flip fmap (++ "abcd") $ do
x <- length
top <- head
return $ replicate x top
Run Code Online (Sandbox Code Playgroud)
一些包(比如microlens和lens)定义(<&>) = flip fmap,允许你写
compute :: String -> String
compute = (++ "abcd") <&> do
x <- length
top <- head
return $ replicate x top
Run Code Online (Sandbox Code Playgroud)
还有一个Category实例(->),它给了我们(>>>) = flip (.).这可能会在视觉上更加清晰:
compute :: String -> String
compute = (++ "abcd") >>> do
x <- length
top <- head
return $ replicate x top
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |