これは、自分自身を書き込むコードの一種です。タイプを結合するだけです。しかし、コードを短くするために使用できる標準ツール(すなわちApplicative
とTraversable
)がいくつかあります。
Data.Traversable
モジュールライフsequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
です。 []
のTraversable
のインスタンスと(->) r
応用的機能に特化した場合、我々が得る:固定引数にリスト内の各関数を適用[]
のうち
sequenceA :: [r -> a] -> r -> [a]
のでsequenceA
ヤンク->
、。
sequenceA [(< 7), (> 7), (== 7)] :: (Num n, Ord n) => n -> [Bool]
-- equivalent to:
\n -> map ($ n) [(< 7), (> 7), (== 7)]
だからあなたの最初の関数は、私が代わりにmconcat . map (All .)
のand
を使用してい
f :: (Num n, Ord n) => n -> Bool
f = and . sequenceA [(< 7), (> 7), (== 7)]
のように記述することができます。
第2の機能の場合は、uncurry
が適切なツールです。 uncurry
をバイナリ関数のリストにマップして、タプルの単項関数のリストを取得しなければならないので、sequenceA
を使用して1つの引数を取り出すことができます。 traverse f = sequenceA . map f
ので、私たちのようにそれを書くことができます。
g :: Ord n => n -> n -> Bool
g = curry $ and . traverse uncurry [(<), (>), (==)]
(NBは、Ord
、>
と<
のいずれか正しく実装インスタンスに対して相互に排他的でなければなりませんので、これらの機能の両方が常にFalse
を返します。。)