惯用的Haskell语法,没有do块或累积括号?

惯用的Haskell语法,没有do块或累积括号?,haskell,emacs,io-monad,Haskell,Emacs,Io Monad,我是Haskell的新手,一直在试图找到一种方法,将多个受IO影响的值传递给一个函数来处理C库。大多数人似乎使用>=putStrLn 这看起来很整洁,但不是基础语言的一部分 从IO污染框中剥离值有没有更省力的符号?也许有一种更干净的方式使用升降机*或fmap?我希望问什么是“惯用语”不要太主观 此外,任何使emacs比(Haskell Ind)模式更好地协作的提示都将不胜感激。谢谢 约翰 编辑:我偶然发现并意识到我编写的lambda链中的嵌套括号是不必要的。然而,社区(和ghc实现者)似乎已经

我是Haskell的新手,一直在试图找到一种方法,将多个受IO影响的值传递给一个函数来处理C库。大多数人似乎使用>=putStrLn 这看起来很整洁,但不是基础语言的一部分

从IO污染框中剥离值有没有更省力的符号?也许有一种更干净的方式使用升降机*或fmap?我希望问什么是“惯用语”不要太主观

此外,任何使emacs比(Haskell Ind)模式更好地协作的提示都将不胜感激。谢谢

约翰


编辑:我偶然发现并意识到我编写的lambda链中的嵌套括号是不必要的。然而,社区(和ghc实现者)似乎已经接受了应用程序风格的使用等,这似乎使代码更易于阅读,尽管计算运算符优先级很麻烦。

您可以使用
liftA2
(或
Control.Monad
中的
liftM2
):


注意:这篇文章是用识字的哈斯克尔写的。您可以将其保存为Main.lhs并在GHCi中尝试


首先简短的评论:您可以去掉
do
中的分号和大括号。另外,
putStrLn
具有类型
IO()
,因此您不需要
return()

您正在寻找这样的东西:

> interactiveConcat :: IO ()
> interactiveConcat = magic g getLine getLine >>= putStrLn
magic
需要什么类型?它返回一个
IO字符串
,使用一个函数返回一个
字符串
,使用通常的
字符串
s,并使用两个
IO字符串
s:

magic :: (String -> String -> String) -> IO String -> IO String -> IO String
我们可以将这种类型推广到

> magic :: (a -> b -> c) -> IO a -> IO b -> IO c
A显示已经有两个函数具有几乎相同的类型:from
Control.Applicative
和from
Control.Monad
。它们是为每个
应用程序定义的
,如果是
liftM2
-
Monad
。由于
IO
是两者的一个实例,因此您可以选择其中一个:

> magic = liftA2
如果您使用GHC 7.10或更高版本,也可以使用
,而无需导入和写入
InteractiveCat

interactiveConcat = g <$> getLine <*> getLine >>= putStrLn
一个简单的检查表明它按预期工作:

$ echo "Hello\nWorld" | runhaskell Main.lhs HelloWorld $echo“Hello\nWorld”| runhaskell Main.lhs 你好世界 工具书类
  • 在Typeclassopedia中
  • 的“一些有用的一元函数”部分

注意:您的“emacs”问题并不完全符合问题的其余部分。这应该是一个问题本身。
IO
不是污点。这是它自己独特的类型。当您开始看到诸如
IO(IO(),IO())
之类的类型签名时,将其视为污点会对您造成很大的伤害。您需要为emacs设置Haskell模式@卡尔已经发生了!我认为形式术语是类型构造函数(我的意思是“IO”后面必须有一个类型参数,即使它只是()类型)。我用“污点”这个词来形容温和的俏皮话幽默,因为使用unsafePerformIO或其他任何方法都会使移植我正在使用的lisp代码变得容易得多。@dfeuer我设置了haskell模式,并尝试了我在melpa和marmalade中发现的大约十几个缩进方案,但这些方案都不适用于简单的事情,就像将函数的参数分散在多行上一样。在发布一个独立的问题之前,我想我可能会尝试一些独立的应用程序(尤其是Leksah)。谢谢你的全面回答。显然,您提到的符号的修改是在.Yup讨论的所谓“函子应用单子方案”的一部分,这已在GHC 7.10中介绍。另请参见您是否正在使用RWH。@flagrant2,除了该页面之外,它还被称为
Applicative=>Monad
建议和缩写AMP。
> interactiveConcat :: IO ()
> interactiveConcat = magic g getLine getLine >>= putStrLn
magic :: (String -> String -> String) -> IO String -> IO String -> IO String
> magic :: (a -> b -> c) -> IO a -> IO b -> IO c
> magic = liftA2
interactiveConcat = g <$> getLine <*> getLine >>= putStrLn
> main :: IO ()
> main = interactiveConcat
$ echo "Hello\nWorld" | runhaskell Main.lhs HelloWorld