首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell简化技术和monads

Haskell简化技术和monads
EN

Stack Overflow用户
提问于 2013-01-10 01:48:12
回答 3查看 196关注 0票数 2

如何减少/简化这些代码(或一般情况下,具有多个输入的代码)?

代码语言:javascript
复制
do
  sex    <- askSex
  name   <- askName
  sayHello sex name

在这种情况下,它已经很短了,但是当它有多个输入时,它看起来很混乱。有没有办法这样做:

代码语言:javascript
复制
sayHello askSex askName
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-10 02:10:10

对于应用函数者来说,这是一个可爱的时刻:

代码语言:javascript
复制
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

它的工作原理有点像我今天给你的前面答案中的fmap,但是对于更多的参数,就像你在这里所做的那样。

使用像my hello这样的函数和应用函数器可以帮助您将IO代码与其余代码分开,这是一个非常好的实践。每次都尝试编写hello而不是sayHello

票数 3
EN

Stack Overflow用户

发布于 2013-01-10 01:58:11

如果你

代码语言:javascript
复制
import Control.Applicative  -- for <$> and <*>
import Control.Monad        -- for join

你可以写

代码语言:javascript
复制
join $ sayHello <$> askSex <*> askName

对于您的示例,您只获取两个参数,这并不是一个很大的胜利。但是对于更多的参数,它可以使代码更清晰。

代码语言:javascript
复制
join $ doSomething <$> getFirst <*> getSecond <*> getThird <*> getForth
票数 5
EN

Stack Overflow用户

发布于 2013-01-11 00:12:11

恼人的是,对于这个问题,胡格尔没有一个简单的答案。这将被称为bind2。如果它是一个只有一个输入的函数,那么你可以使用=<<,我称之为bind1的中缀版本。

代码语言:javascript
复制
sayHello =<< askName

但是对于多个输入,我们就不走运了。无论出于什么原因,标准库都没有提供这样的功能:

代码语言:javascript
复制
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

当然,您可以自己定义它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14243303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档