2010-12-11 10 views
1

リストの要素間で論理的で機能する関数を書くにはどうすればよいですか?Haskell IO Bool fold question

私はこれを書いている:

iand :: [IO Bool] -> IO Bool 

iand [] = return (True) 
iand (x:xs) = do 
    a <- x 
    b <- iand(xs) 
    return (a && b) 

しかし、それはunconsciceのようです。

この機能をfoldM(liftM)でどのように書き直すことができますか?

ありがとうございます。

答えて

10

プレリュード機能and :: [Bool] -> Boolほとんど何をしたいんが、それはモナドではありません。一般に、引数の1つの関数をモナドに持ち上げるには、Control.MonadのliftM :: Monad m => (a -> b) -> m a -> b aが必要です。しかし、より一般的には、Preludeのfmap :: Functor f => (a -> b) -> f a -> f bを使用することができます。すべてのモナドはファンクタなので、これは問題ありません。したがって、あなたはしかし

fand' :: Functor f => f [Bool] -> f Bool 
fand' = fmap and 

を使用することができ、時間の少なくとも90%が、私はちょうど fmapためControl.Applicativeの <$>シノニムを使用して、よりおそらく and <$> xs fmap and xsように、そのインラインを書き、またはでしょう。

もちろん、私が気づいたように、これはあなたが望むものではありません。そのためには、Preludeのsequence :: Monad m => [m a] -> m [a]が必要です。あなたは今の機能[m a] -> m [a]、および機能f [Bool] -> f Boolを持っているので、我々はこれらを組み合わせることができます。

mand :: Monad m => [m Bool] -> m Bool 
mand = liftM and . sequence 

ある意味でfmapの 『よりよい』が、それは追加のFunctor mを課す、ので、私はfmapからliftMに切り替え制約。そのは、は問題にならないはずですが、歴史的な理由からそうかもしれないので、私は安全にプレーしました。

また、「sequenceについてはどのように知りましたか」と問えるかもしれません。その答えは素晴らしいHoogleです。これにより、Haskell関数を名前またはで検索することができます。だから、あなたが約liftM :: Monad m => (a -> b) -> m a -> m bを知っていたので、あなたはMonad m => [m a] -> m [a]のようなものが必要であることに気づいたかもしれません。そのためのフーグリングdoes indeed turn up sequence


1:あるいは、少なくとも、彼らは被ためにすべき歴史的な理由で、しかし、これは必ずしもそうではありません。

+0

ありがとう!しかし、次のように書かれています: "予想される型' m 'と推定型 '[]'をマッチさせることができませんでした。何が問題なの? – 4DA

+0

@ドミトリー:私はタイプミスしているので私は 'mad :: Monad m => m [Bool] - > m Bool'を主張しました。この練習の*ポイント*は' Monad m => [m Bool ] - > m Bool'。そのタイプのアサーションを修正すると、すべてが機能します。私はそれに対応して私の答えを編集しました。 –

1

これはiand list = foldl (&&) True listではありませんか?

+0

いいえ、それは '[Bool] - > Bool'型の関数で、通常の' and'のように動作しますが、遅延は少なくなります。ドミトリーが望むのは 'IO Bool] - > IO Bool'の関数です。 – sepp2k

+0

右。それを逃した。混乱させて申し訳ありません。 –

2

あなたはIO [Bool]にあなたの[IO Bool]をオンにするタイプIO [Bool] -> IO Boolsequenceの関数に([Bool] -> Bool型を持つ)andをオンにするliftMを使用することができます。

だからあなたの関数は次のようになります。

iand ibs = liftM and (sequence ibs)