Haskell简化技术与单子

Haskell简化技术与单子,haskell,Haskell,如何减少/简化此代码(或者通常是具有多个输入的代码) do sex <- askSex name <- askName sayHello sex name ?如果您 import Control.Applicative -- for <$> and <*> import Control.Monad -- for join import Control.Applicative——用于和 Monad——用于连接 你可以写

如何减少/简化此代码(或者通常是具有多个输入的代码)

do
  sex    <- askSex
  name   <- askName
  sayHello sex name

如果您

import Control.Applicative  -- for <$> and <*>
import Control.Monad        -- for join
import Control.Applicative——用于和
Monad——用于连接
你可以写

join $ sayHello <$> askSex <*> askName
加入$sayHello askSex askName
对于您的示例,您只获取两个参数,这不是一个大的胜利。但是对于更多的参数,它可以使代码更清晰

join $ doSomething <$> getFirst <*> getSecond <*> getThird <*> getForth
join$doSomething getFirst getSecond getThird getForth

对于应用程序函子来说,这是一段美好的时光:

import Control.Applicative -- at the top of your module before any functions

hello "Male" name = "Hi, " ++ name ++ ", that's a cool name."
hello "Female" name = "Hello, " ++ name ++ ", that's a pretty name."

greet = hello <$> askSex <*> askName >>= putStrLn
import Control.Applicative——在任何函数之前的模块顶部
你好“男”name=“你好,++name++”,这是个很酷的名字。”
你好“女”name=“你好,++name++”,这是个漂亮的名字。”
问候=你好askSex askName>>=putStrLn
它的工作原理有点像我今天给你的前面的答案中的
fmap
,但是对于更多的参数,就像你在这里看到的那样


将my
hello
等函数与应用程序函子一起使用,可以帮助您将IO代码与代码的其余部分分开,这是一种非常好的做法。试着每次写
hello
而不是
sayHello

令人恼火的是,胡格尔并没有一个简单的答案。这将被称为
bind2
。如果它是一个只有一个输入的函数,那么你可以使用
=这段代码看起来非常简单,任何比这短的东西都很可能是奇怪的。如果您请求大量相同类型的输入,您可能会映射这些操作,但在本例中不会。请查看中的函数,特别是
liftM2
。正如sabauma所说,使用
liftM2
。这是对原始代码的抽象,也是您想要的。如果从do块的开头包含
do
,则更为清晰。遗憾的是,习惯用法括号没有包含在Haskell中:
join(| doSomething getFirst getSecond getThird getForth |)
会更好。嗯,总是有
import Control.Applicative -- at the top of your module before any functions

hello "Male" name = "Hi, " ++ name ++ ", that's a cool name."
hello "Female" name = "Hello, " ++ name ++ ", that's a pretty name."

greet = hello <$> askSex <*> askName >>= putStrLn
sayHello =<< askName
bind2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
bind2 f mx my = do
  x <- mx
  y <- my
  f x y

...

bind2 sayHello askSex askName