例如,我想开发sum函数,它将显示中期结果.
我的基本功能是:
ownPlus start list = foldr (+) start list
Run Code Online (Sandbox Code Playgroud)
我想在Writer Monad里面添加foldl.所以我的功能原型是:
sumWithLogging :: (Show a, Num a) => a -> [a] -> Writer String a
sumWithLogging start list = foldr ((+) do tell ["msg"]) start list
Run Code Online (Sandbox Code Playgroud)
我写这个函数有问题.但我希望我的结果看起来像这样:
*Main> runWriter $ sumWithLogging 0 [1..2]
(3,"(1+(2+0))")
Run Code Online (Sandbox Code Playgroud)
scanl 可能是一个有用的功能.
来自Hoogle:
scanl类似于foldl,但从左侧返回连续减少值的列表.
因此,您可以看到渐进式结果:
?> scanl (+) 0 [1,2,3]
[0,1,3,6]
?> scanl (flip (:)) [] [1,2,3,4,5]
[[],[1],[2,1],[3,2,1],[4,3,2,1],[5,4,3,2,1]]
Run Code Online (Sandbox Code Playgroud)
如果你想要类似作家的结果,那很简单.您甚至不需要使用Writer,并且避免使用过于复杂的功能总是好的.
logSum = foldl (\(n,s) x -> (n+x, "(" ++ s ++ "+" ++ show x ++ ")")) (0,"0")
?> logSum [1..2]
(3, "((0+1)+2)")
Run Code Online (Sandbox Code Playgroud)
我可以补充说,foldl应该描述左关联操作,但是括号意味着你正在编写它们的方式正确的关联性.
如果你想要它是右关联的(比如(:)运算符),那很简单; 用途foldr:
logSumR = foldr (\x (n,s) -> (x:n, show x ++ " : " ++ s)) ([],"[]")
Run Code Online (Sandbox Code Playgroud)
以便:
? logSumR [1,2,3,4,5]
([1,2,3,4,5], "1 : 2 : 3 : 4 : 5 : []")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
218 次 |
| 最近记录: |