我对 Haskell 相当陌生,并且一直在尝试找到一种方法将多个受 IO 污染的值传递给处理 C 库的函数。大多数人似乎在 do 块中使用 <- 运算符,如下所示:
g x y = x ++ y
interactiveConcat1 = do {x <- getLine;
y <- getLine;
putStrLn (g x y);
return ()}
这让我觉得我在做 C,除了 emacs 不能自动缩进。我试着用更 Lispy 的风格来写这个:
interactiveConcat2 = getLine >>= (\x ->
getLine >>= (\y ->
putStrLn (g x y) >>
return () ))
这看起来像一团糟,并且有一串闭括号,你必须在最后数数(除此之外,emacs 可以在 Lisp 中可靠地协助完成这项任务,但在 Haskell 中则不行)。还有一种说法是
import Control.Applicative
interactiveConcat3 = return g <*> getLine <*> getLine >>= putStrLn
它看起来很整洁,但不是基础语言的一部分。
从 IO 污点盒中剥离值是否有任何不那么费力的符号?也许有更清洁的方式使用 lift* 或 fmap?我希望不要太主观地问什么被认为是“惯用的”?
此外,任何使 emacs 比(Haskell Ind)模式更好地协作的技巧将不胜感激。谢谢!
约翰
编辑:我偶然发现了https://wiki.haskell.org/Do_notation_considered_harmful并意识到我写的 lambda 链中的嵌套括号是不必要的。然而,社区(和 ghc 实现者)似乎已经接受了 Applicative-inspired 风格,使用 、<*> 等,这似乎使代码更容易阅读,尽管在弄清楚运算符优先级方面很头疼。