この Haskell 関数の値はどこから来たのでしょうか?
質問
次の関数があるとします。
sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map f xs)
where f (x,y) = x+y
結果として sumAll [(1,1),(2,2),(3,3)]
になるだろう 12
.
私が理解できないのは、どこにあるのかということです (x,y)
価値観はから来ています。まあ、私は彼らがから来ていることを知っています xs
変数ですが、その方法がわかりません。つまり、where キーワードを使用せずに上記のコードを直接実行すると、次のようになります。
sumAll xs = foldr (+) 0 (map (\(x,y) -> x+y) xs)
そして、トップコードでは、どうやって f
変数と (x,y)
変数は以下を表します (\(x,y) -> x+y)
ラムダ式。
解決
Haskell では、関数はファーストクラスのデータ型です。
これは、整数や文字列などの他のタイプのデータと同様に関数を渡すことができることを意味します。
上記のコードでは、「f」を関数として宣言しています。この関数は 1 つの引数 a (2 つの値 (x,y) のタプル) を受け取り、(x + y) の結果を返します。
foldr は、バイナリ関数 (この場合は +)、開始値 (0)、および反復処理する値の配列という 3 つの引数を取る別の関数です。
つまり、「where f (x,y) = x + y」は単にスコープ付きの省略表現です。
sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map myFunctionF xs)
myFunctionF :: (Int,Int) -> Int
myFunctionF (x,y) = x + y
編集:フォルダーの仕組みがわからない場合は、次を確認してください。 Haskell リファレンス Zvon以下は、foldl/map の実装例です。
foldl :: (a -> b -> b) -> b -> [a] -> b
foldl _ x [] = x
foldl fx (y:ys) = foldl f (f y x) ys
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = (f x) : (map f xs)
他のヒント
うまくいけば、これは役立ちます。キーはf
がペアであるリストの要素に適用されることである。
sumAll [(1,1),(2,2),(3,3)]
-- definition of sumAll
= foldr (+) 0 (map f [(1,1),(2,2),(3,3)])
-- application of map
= foldr (+) 0 (f (1,1) : map f [(2,2),(3,3)])
-- application of foldr
= 0 + foldr (+) (f (1,1)) (map f [(2,2),(3,3)])
-- application of map
= 0 + foldr (+) (f (1,1)) (f (2,2) : map f [(3,3)])
-- application of foldr
= 0 + (f (1,1) + foldr (+) (f (2,2)) (map f [(3,3)]))
-- application of f
= 0 + (2 + foldr (+) (f (2,2)) (map f [(3,3)]))
-- application of map
= 0 + (2 + foldr (+) (f (2,2)) (f (3,3) : map f []))
-- application of foldr
= 0 + (2 + (f (2,2) + foldr (+) (f (3,3)) (map f [])))
-- application of f
= 0 + (2 + (4 + foldr (+) (f (3,3)) (map f [])))
-- application of map
= 0 + (2 + (4 + foldr (+) (f (3,3)) []))
-- application of foldr
= 0 + (2 + (4 + f (3,3)))
-- application of f
= 0 + (2 + (4 + 6))
= 0 + (2 + 10)
= 0 + 12
= 12
はない答えが、私はあなたの関数fことを指摘しなければならないと思った。
f (x, y) = x + y
のように表すことができます。
f = uncurry (+)
所属していません StackOverflow