原问题
利亚,在对于更多的 Monad http://learnyouahaskell.com/for-a-few-monads-more显示此功能,
solveRPN :: String -> Maybe Double
solveRPN st = do
[result] <- foldM foldingFunction [] (words st)
return result
它结合使用模式匹配do
表达确保 monad 出来foldM
包装一个单例列表.
为了真正了解事物的本质do
的表达以及Monad
,我一直在重写那本书中的大多数例子>>=
and >>
而不是do
表达,一种在某处建议的做法现实世界哈斯克尔 http://book.realworldhaskell.org/read/我也有,不过不记得是哪一章了。
对于上面的功能,我有点困惑。不使用 的最简洁的编写方式是什么do
表达?我能想到的最好的办法是
solveRPN :: String -> Maybe Double
solveRPN s = foldM step [] (words s) >>= \x -> case x of
[y] -> Just y
_ -> Nothing
但我希望有一些更干净的东西,因为这个噪音很大,原因有两个:
- 它使用 lambda
- 它使用
case
表达式,看起来并不比if
-then
-else
.
这个问题 https://stackoverflow.com/questions/59226842/how-to-pattern-match-an-intermediate-value-in-haskell/59226926#59226926与现在有关。
I asked 另一个问题 https://stackoverflow.com/questions/62803061/can-this-function-be-written-in-point-free-style-if-not-why/这实际上强调了这一问题的基本问题:
我该如何拉动head
在列表之外并且仅对单例列表成功?
这与Maybe
将结果包装在solveRPN
.
Update
The 我在那里接受的答案 https://stackoverflow.com/a/62803320/5825294针对上述问题提出了明确的解决方案:
func :: [a] -> a
func = foldr1 (const (const undefined))
可以用来轻松书写solveRPN
以无点风格:
solveRPN :: String -> Maybe Double
solveRPN st = foldM foldingFunction [] (words st) >>= Just . foldr1 (const (const undefined))
然而,这绝对不能令人满意,因为它没有充分利用Maybe
monad,在运行时失败而不是返回Nothing
当输出不正确时。
我认为,玩弄这个可能会让我或其他人回答我最初的问题,而无需do
/case
/帮手。