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