私はHaskellを学ぼうとしていて、複数のパラメーターを受け取る関数を使用して特定のリストをフィルター処理し、リストの各要素を他の不変の要素とともに関数に渡して、新しいリストを作成する方法を考えました。
これを実行して、bool関数を使用してリストをフィルタリングできることを理解しています。
newList = filter theFunction aList
しかし、theFunctionが次のような他のパラメーターを受け取るとどうなりますか?
theFunction -> elementOfAList -> Int -> Bool
次に、関数の別の要素を解析しながら、リストの各要素をフィルタリングするにはどうすればよいですか?どんな助けでも大歓迎です:)
編集->さらに情報を提供するために、[1..10]の整数のリストが必要な場合、2つの整数を受け取り、最初の整数が小さい場合はtrueを返す関数でフィルター処理されます。どうすればよいですか?それ?
その場合、次のように部分的に適用された述語関数を使用します
-- theFunction :: elementOfAList -> Int -> Bool -- "::" means, "is of type"
newList = filter (flip theFunction i) aList
なぜなら
flip theFunction i x = theFunction x i
の定義によりflip
、flip theFunction
タイプもありInt -> elementOfAList -> Bool
ます:
flip :: (a -> b -> c ) -> b -> a -> c
theFunction :: a -> Int -> Bool
flip theFunction :: Int -> a -> Bool
flip theFunction (i :: Int) :: a -> Bool
ここで、i
はInt
他の場所で定義されている値です。a
は型変数です。つまり、リストの要素の型のように、任意の型にすることができます(つまり、リストの場合、aList :: [a]
各要素は同じ型を持ちますa
)。
たとえば、をtheFunction x i = x < i
呼び出すとfilter (flip theFunction 5) aList
、結果のリストにそのすべての要素がaList
5より小さいままになります。通常、これはfilter (< 5) aList
、演算子セクション((< 5)
1つの例であり、完全に同等)を使用してと記述されflip theFunction 5
ます。
上記のフィルタリングでは、リストのすべての要素を呼び出す際に同じInt
値が使用さi
れます。それを再計算したい場合は、別のパターン(つまり、高階関数)で実行されます。theFunction
x
aList
Int
mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
によって検出されているすべての要素をintのリストに保持したいとしますtheFunction
。その後、あなたはそれを次のようにすることができます
theFunction :: elementOfAList -> Int -> Bool
foo :: Int -> [Int] -> [Int]
foo i xs = concat (snd (mapAccumL g i xs)) -- normally written as
-- concat $ snd $ mapAccumL g i xs -- or
-- concat . snd $ mapAccumL g i xs -- or even
-- concat . snd . mapAccumL g i $ xs
where
g acc x -- g :: (acc -> x -> (acc, y)) according to mapAccumL's signature
| theFunction x acc = (x, [x]) -- include `x` in output, and update the acc
| otherwise = (acc, []) -- keep the accumulated value, and skip this `x`
x
とacc
は両方とも同じ役割(タプルの最初の要素)で使用されるため、両方とも同じタイプである必要があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加