2

このコード (または一般に、複数の入力を持つコード) をどのように削減/簡素化できますか?

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

この場合、すでに非常に短いですが、複数の入力になると、乱雑に見えます。次のようなことを行う方法はありますか:

sayHello askSex askName

?

4

3 に答える 3

5

もし、あんたが

import Control.Applicative  -- for <$> and <*>
import Control.Monad        -- for join

あなたは書ける

join $ sayHello <$> askSex <*> askName

あなたの例では、2 つのパラメーターのみを取得していますが、これは大きなメリットではありません。ただし、パラメーターの数が多い場合は、コードをより明確にすることができます。

join $ doSomething <$> getFirst <*> getSecond <*> getThird <*> getForth
于 2013-01-09T17:58:11.137 に答える
3

これは、ApplicativeFunctorsにとって素敵な時間です。

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に機能しますが、あなたがここに持っているように、より多くの議論のために。

私のような関数helloをアプリケーションファンクターで使用すると、IOコードを残りのコードから分離するのに役立ちます。これは非常に良い習慣です。毎回ではhelloなく、書くようにしてください。sayHello

于 2013-01-09T18:10:10.310 に答える
1

厄介なことに、フーグルはこれについて簡単な答えを持っていません。これは と呼ばれbind2ます。入力が 1 つしかない関数の場合は=<<、私が と呼ぶものの中置バージョンである を使用できますbind1

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

もちろん、自分で定義することもできます。

于 2013-01-10T16:12:11.240 に答える